【问题标题】:PHP: Scraping links and text output to filePHP:将链接和文本输出到文件
【发布时间】:2014-02-02 09:55:13
【问题描述】:

我的网站上有一些视频源,我想在 XBMC 中打开,但无法打开。

所以我正在考虑抓取链接和频道名称并将它们输出到我的媒体中心可以打开的一些文件(每个频道一个文件)。我必须在一个小型的 linux 机器上完成,因为我不知道 bash 或 python,但是一些 php(不多),我想我会使用 PHP 来完成这项任务。但是我在使用正则表达式和 php 的输出时遇到了一些问题。

包含提要的网站如下所示:

... Lots of HTML before this part

<a href="javascript:changeChannel('http://live.provider.com/something/something_else/1.abcdefg.m3u8', 1);">First Channel</a><br>
<a href="javascript:changeChannel('http://live.provider.com/something/something_else/2.abcdefg.m3u8', 2);">Second Channel</a><br>
<a href="javascript:changeChannel('http://live.provider.com/something/something_else/3.abcdefg.m3u8'', 3);">Third Channel</a><br>

.... //  More channels and other html below here..

我要提取的是链接和url文本:

例如:http://live.provider.com/something/something_else/1.abcdefg.m3u8

例如:第一频道

等等

目前我的代码如下所示:

$streamSite = "http://link.to/feed-website.html";

function writeFile($url, $channel) {
        $File = $channel.".strm";
        $Handle = fopen($File, 'w');
        fwrite($Handle, $url);
        fclose($Handle);
}

  $input = @file_get_contents($streamSite) or die("Could not access file: $url");
  $regexp = "(((f|ht){1}tp:\/\/)[-a-zA-Z0-9@:%_\+.~#?&\/\/=]+)";

  if(preg_match_all($regexp, $input, $matches, PREG_SET_ORDER)) {
    foreach($matches as $match) {
        echo serialize($match);
        echo "\r\n";
    }
    unset($match);
  }
?>

使用当前的正则表达式,我应该抓取 url。我已经在http://regexr.com/ 上测试了正则表达式,它在那里工作。

目前我只是将结果打印到控制台。

当前输出如下所示:

a:3:{i:0;s:97:"http://live.provider.com/something/something_else/1.abcdefg.m3u8";i:1;s:7:"http://";i:2;s:2:"ht";}
a:3:{i:0;s:97:"http://live.provider.com/something/something_else/2.abcdefg.m3u8";i:1;s:7:"http://";i:2;s:2:"ht";}
a:3:{i:0;s:97:"http://live.provider.com/something/something_else/3.abcdefg.m3u8";i:1;s:7:"http://";i:2;s:2:"ht";}

我不知道链接之前和之后的文本来自哪里。是我的序列化失败还是正则表达式?

你能帮我处理正则表达式吗,这样我就可以抓取 url 和文本并将其放入一个数组中,然后我可以循环并使用我编写的函数将内容写入 .strm 文件?

提前致谢!

【问题讨论】:

    标签: php regex


    【解决方案1】:

    在 php 中,'()' 是 capturing groups。它们基本上用于匹配由整个正则表达式匹配的文本的子部分。与捕获组相反,我们有non-capturing groups。它们是“(?:)”。

    在这种情况下,可以使用捕获组来分别获取 url 和文本,尽管我们需要匹配整个文本。 这应该适用于抓取 url 和文本。

    <?php
    $regexp = "/((?:(?:f|ht){1}tp:\/\/)[-a-zA-Z0-9@:%_\+.~#?&\/\/=]+).*?>(.*?)</";
    if(preg_match_all($regexp, $input, $matches, PREG_SET_ORDER)) {
        foreach($matches as $match) {
            var_dump($match);
            echo "\r\n";
        }
        unset($match);
    }
    /*
        For the present set of inputs, the output is- 
        array
          0 => string 'http://live.provider.com/something/something_else/1.abcdefg.m3u8', 1);">First Channel<' (length=86)
          1 => string 'http://live.provider.com/something/something_else/1.abcdefg.m3u8' (length=64)
          2 => string 'First Channel' (length=13)
        array
          0 => string 'http://live.provider.com/something/something_else/2.abcdefg.m3u8', 2);">Second Channel<' (length=87)
          1 => string 'http://live.provider.com/something/something_else/2.abcdefg.m3u8' (length=64)
          2 => string 'Second Channel' (length=14)
        array
          0 => string 'http://live.provider.com/something/something_else/3.abcdefg.m3u8'', 3);">Third Channel<' (length=87)
          1 => string 'http://live.provider.com/something/something_else/3.abcdefg.m3u8' (length=64)
          2 => string 'Third Channel' (length=13)
    
    */
    ?>
    

    这里的array[0] 匹配整个字符串,array[1] 只捕获url,array[2] 只捕获文本。

    【讨论】:

    • 太棒了!我的脚本使用您的代码工作。非常感谢!你能帮我做最后一件事吗?请编辑正则表达式以仅允许链接中带有“m3u8”的链接
    • 我认为这个正则表达式会起作用 - "/((?:(?:f|ht){1}tp:\/\/)[-a-zA-Z0-9 @:%_\+.~#?&\/\/=]+.m3u8).*?>(.*?)"
    • 它做到了!非常感谢。发现我需要修改一些提要以便它们在 XBMC 中工作,但是在使用 stristr_array、strstr 和一些正则表达式玩了 arround 之后,我终于让一切正常了 :) 再次感谢!
    • Kamehameha:我能再打扰你一下吗?我的提供商更改了链接 - 现在包含括号。像这样 javascript:changeChannel('bs-live.provider.com/something/something_else/Channel(C9)/…', 54);
    • @RazziaDK 嗨,试试这个 - ((?:(?:f|ht){1}tp:\/\/)[-a-zA-Z0-9@:%_\+.~#?&amp;\/\/=\(\)]+).*?&gt;(.*?)&lt;。(我在 url 的事物列表中添加了 ())这仍然假定 url be-live.provider... 是前面是 http 或 ftp...
    【解决方案2】:

    以下正则表达式从具有 href="javascript:changeChannel&lt;a&gt; 元素中提取相关信息,如您的示例数据所示:

    ~(?<=<a href="javascript:changeChannel\(')([^']+)',\s(\d+)\);">(.+?)</a>~
    

    这样做:

    $str = <<<STR
      <a href="javascript:changeChannel('http://live.provider.com/something/something_else/1.abcdefg.m3u8', 1);">First Channel</a><br>
      <a href="javascript:changeChannel('http://live.provider.com/something/something_else/2.abcdefg.m3u8', 2);">Second Channel</a><br>
      <a href="javascript:changeChannel('http://live.provider.com/something/something_else/3.abcdefg.m3u8', 3);">Third Channel</a><br>
    STR;
    
    $regex = <<<REGEX
      ~(?<=<a href="javascript:changeChannel\(')([^']+)',\s(\d+)\);">(.+?)</a>~
    REGEX;
    
    preg_match_all($regex, $str, $matches);
    
    echo '<pre>' . print_r($matches, true) . '</pre>';
    

    输出

    Array
    (
        [0] => Array
            (
                [0] => http://live.provider.com/something/something_else/1.abcdefg.m3u8', 1);">First Channel
                [1] => http://live.provider.com/something/something_else/2.abcdefg.m3u8', 2);">Second Channel
                [2] => http://live.provider.com/something/something_else/3.abcdefg.m3u8', 3);">Third Channel
            )
    
        [1] => Array
            (
                [0] => http://live.provider.com/something/something_else/1.abcdefg.m3u8
                [1] => http://live.provider.com/something/something_else/2.abcdefg.m3u8
                [2] => http://live.provider.com/something/something_else/3.abcdefg.m3u8
            )
    
        [2] => Array
            (
                [0] => 1
                [1] => 2
                [2] => 3
            )
    
        [3] => Array
            (
                [0] => First Channel
                [1] => Second Channel
                [2] => Third Channel
            )
    
    )
    

    希望它是您正在寻找的东西:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 2019-04-11
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多