【问题标题】:PHP scraper - regular expressionsPHP 刮板 - 正则表达式
【发布时间】:2012-02-23 00:07:47
【问题描述】:

我正在尝试使用 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我如何得到哈希后的数字?

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

【问题讨论】:

    标签: php regex scraper


    【解决方案1】:

    鉴于标题“Welcome visitor #100”和&lt;title&gt; 标签不超过一次出现的事实,表达式应该是:

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

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

    虽然 - 如前所述 - &lt;title&gt; 标签(应该)出现不超过一次,但该模式

    <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');
    }
    

    【讨论】:

    • 好的,谢谢您的解释。关于如何处理多次出现的标签的任何提示。我可以在 DOM 中使用它们的父级访问它们吗?
    【解决方案2】:

    您只需要更改正则表达式以匹配您需要的任何内容。如果您要多次使用该图块,最好保存整个图块并稍后对其进行操作,否则只需获得您需要的东西。

    /&lt;title&gt;.*((?&lt;=#)\d*).*&lt;\/title&gt;/i

    将专门匹配哈希后的数字。它不会匹配没有哈希的数字。

    编写正则表达式的方法有很多种,这取决于您想要的通用性或特定性。

    你也可以这样写得到任意数字:

    /&lt;title&gt;.*(\d)*.*&lt;\/title&gt;/i

    【讨论】:

    • 谢谢,如果有多个哈希怎么办,有没有指定最后一个哈希?
    • 第一个将只匹配一个哈希后跟数字。如果你有一个散列,后面跟着除数字之外的任何东西,它不会有任何区别
    • 谢谢,但我问的是不是散列,而是一个空格或一个常见的字符,我可能想在最后一个实例之后找到数字。我想我最好去阅读有关使用正则表达式的信息。
    【解决方案3】:

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

    一些进一步的说明:

    • 此类事情请使用 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>
      

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

    【讨论】:

      猜你喜欢
      • 2013-06-27
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-23
      • 2013-05-30
      相关资源
      最近更新 更多