PHP:将链接和文本输出刮到文件

时间:2014-02-02 00:06:24

标签: php regex

我在网站上有一些视频供稿,我想在XBMC中打开,但不能。

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

包含Feed的网站如下所示:

... 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..

我想要提取的是链接和网址文字:

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

Ex:First Channel

目前我的代码如下:

$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);
  }
?>

目前的正则表达式我应该抓住网址。我在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文件中吗? / p>

提前致谢!

2 个答案:

答案 0 :(得分:0)

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

在这种情况下,虽然我们需要匹配整个文本,但捕获组可以用于分别获取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)

*/
?>

这里数组[0]匹配整个字符串,数组[1]只捕获网址,数组[2]只捕获文本。

答案 1 :(得分:0)

以下正则表达式从示例数据中<a>的{​​{1}}元素中提取相关信息:

href="javascript:changeChannel

所以:

~(?<=<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>';

希望这是你正在寻找的东西:)