PHP scraper - 正则表达式

时间:2012-02-23 00:07:47

标签: php regex scraper

我正在尝试使用php跟踪tutorial for web scraping

我完全理解发生了什么,但是我不知道如何过滤已被抓取的内容以获得我想要的内容。例如:

<?php
$file_string = file_get_contents('page_to_scrape.html');
preg_match('/<title>(.*)<\/title>/i', $file_string, $title);
$title_out = $title[1];
?>

我看到(.*)将检索标题标签之间的所有内容,我可以使用正则表达式来获取特定信息。在标题里面说Welcome visitor #100我怎样才能获得散列后的数字?

或者我是否必须检索标签之间的所有内容,然后再操作它?

3 个答案:

答案 0 :(得分:3)

鉴于标题为“欢迎访客#100”,并且<title>标签的出现次数不超过一次,表达式应为:

preg_match('~<title>Welcome visitor #(\d+)</title>~', ...);

很多人都会争论never use regular expressions to parse (X)HTML;但是,对于这项任务,上述内容就足够了。

虽然 - 如前所述 - <title>标签(应该)只出现一次,模式

<title>(.*)</title>

也会匹配这个:

<title>Welcome visitor <title>#<title>100blafoobar</title>

(.*)是允许这一点的部分。一旦您从更改中抓取数据页面,正则表达式可能会停止工作。


编辑正确筛选多个元素及其属性的方法:

$dom = new DomDocument;
$dom->loadHTML($page_content);

$elements = $dom->getElementsByTagName('a');

for ($n = 0; $n < $elements->length; $n++) {
    $item = $elements->item($n);
    $href = $item->getAttribute('href');
}

答案 1 :(得分:2)

您只需要更改正则表达式以匹配您需要的任何内容。如果你不止一次使用瓷砖,最好保存整个并稍后操作它,否则只需得到你需要的东西。

/<title>.*((?<=#)\d*).*<\/title>/i

会在哈希后专门匹配一个数字。它与没有哈希值的数字不匹配。

有很多方法可以编写正则表达式,这取决于你想要的一般或具体程度。

您也可以这样写这个来获取任何数字:

/<title>.*(\d)*.*<\/title>/i

答案 2 :(得分:0)

我首先获取标题标签,然后进一步处理标题。其他答案包含完成此任务的完全有效的解决方案。

进一步说明:

  • 请使用DOMDocument进行此类操作,因为它更安全(您的正则表达式可能会在某些特定的HTML页面上中断)
  • 请使用非贪婪版.*.*? ,否则您会遇到类似以下内容的有趣内容:

    <html>
        <head>
            <title>a</title>
        </head>
        <body>
            <title>test</title> <!-- not allowed in HTML, but since when does the web pages online actually care about that? -->
        </body>
    </html>
    

现在,您将匹配<title>a</title>...<title>test</title>之间的所有内容,包括介于两者之间的所有内容。