【问题标题】:Selective extraction of data from external site using DOM PHP web crawler使用 DOM PHP 网络爬虫从外部站点选择性提取数据
【发布时间】:2017-03-01 08:37:51
【问题描述】:

我有一个运行良好的 PHP dom 网络爬虫。它从(外部)论坛站点提取提到的标签及其链接到我的页面。

但最近我遇到了一个问题。喜欢

这是论坛数据的 HTML::

<tbody>
<tr>
    <td width="1%" height="25">&nbsp;</td>
    <td width="64%" height="25" class="FootNotes2"><a href="/files/forum/2017/1/837880.php" target="_top" class="Links2">Hispanic Study Partner</a> - dreamer1984</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="14%" height="25" class="FootNotes2" align="center">02/28/17 01:42</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="8%" height="25" align="Center" class="FootNotes2">0</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="9%" height="25" align="Center" class="FootNotes2">200</td>
</tr>
<tr>
    <td width="1%" height="25">&nbsp;</td>
    <td width="64%" height="25" class="FootNotes2"><a href="/files/forum/2017/1/837879.php" target="_top" class="Links2">nbme</a> - monariyadh</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="14%" height="25" class="FootNotes2" align="center">02/27/17 23:12</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="8%" height="25" align="Center" class="FootNotes2">0</td>
    <td width="1%" height="25">&nbsp;</td>
    <td width="9%" height="25" align="Center" class="FootNotes2">108</td>
</tr>
</tbody>

现在,如果我们将上述代码(表格数据)视为该站点中唯一可用的语句。如果我尝试使用网络爬虫来提取它,

<?php
    require_once('dom/simple_html_dom.php'); 
    $html = file_get_html('http://www.sitename.com/');
    foreach($html->find('td.FootNotes2') as $element) {
    echo $element;
}
?>

它提取里面的所有数据,类名为“FootNote2”

现在,如果我想从第一个标签/行中提取标签中的特定数据,例如“dreamer1984”和“monariyadh”之类的名称。

如果我想从具有相同类名的 3rd(跳过其余部分)中提取数据怎么办。

请注意,我可以像使用“正则表达式”一样

preg_match_all('/<td.+?FootNotes2.+?<a.+?<\/a> - (?P<name>.*?)<\/td>.+?<td.+?FootNotes2.+?(?P<date>\d{2}\/\d{2}\/\d{2} \d{2}:\d{2})/siu', $subject, $matchs);

foreach ($matchs['name'] as $k => $v){
    var_dump('name: '. $v, 'relative date: '. $matchs['date'][$k]);
}

但我更喜欢在 DOM 解析器中找到解决方案... 任何帮助表示赞赏..

【问题讨论】:

标签: php web-crawler simple-html-dom


【解决方案1】:

正如我在评论中所说,一些文本处理是不可避免的,但是您可以像这样获取与 td 关联的文本元素:

require_once('dom/simple_html_dom.php'); 
$html = file_get_html('http://www.sitename.com/');
foreach ($html->find("tr") as $row) {
        $element = $row->find('td.FootNotes2',0);
        if ($element == null) { continue; }
        $textNode = array_filter($element->nodes, function ($n) {
            return $n->nodetype == 3;        //Text node type, like in jQuery     
        });

        if (!empty($textNode)) {
            $text = current($textNode);
            echo $text;         
        }

    }  

这呼应了:

- dreamer1984
- monariyadh

随心所欲。

更新为仅查找每个 tr 的第一个 td。

【讨论】:

  • 好的,但是如何避免最后两件事,比如数字,如“0, 200 和 0, 108”..... 如果我想呼应这个名字怎么办(dreamer1984 ) 和不同地方的日期...?
  • @harishk 已更新。现在它找到行和每行的第一个td.Footnotes2。如果您还想要第三个元素,那么也可以使用find(...,2)
  • 老兄,它会打印出准确的内容,但会反复给出两个错误,例如 Warning: array_filter() expects parameter 1 to be array, null given Notice: Trying to get property of non-object for $textNode = array_filter($element-&gt;nodes, function ($n) { line...
  • @harishk 你可以检查$element 是否不为空
  • 怎么做?
【解决方案2】:

如果您只想提取文本(而不是标签及其包含)

foreach ($html->find("td.FootNotes2") as $element) {

    $children = $element->children; // get an array of children
    foreach ($children AS $child) {
      $child->outertext = ''; // This removes the element, but MAY NOT remove it from the original $myDiv
    }
    echo $element->innertext."<br>";
}

o/p:

- dreamer1984
02/28/17 01:42
0
200
- monariyadh
02/27/17 23:12
0
108

【讨论】:

  • 是的,但我只需要前两列,,,,
  • 确实,其他人的回答给了我解决方案,但除非我使用 while 循环,否则它给出了错误...请到讨论室检查一下...@987654321 @
  • 哥们你在吗?
【解决方案3】:

无论哪种方式,您都必须使用正则表达式,所以没有必要过度复杂化:

foreach($html->find('tr') as $tr) {
  echo preg_replace('/.* - /', '', $tr->find('td',1)->text()) . "\n";
  echo $tr->find('td',3)->text() . "\n";
}

我真的不喜欢 apokryfos 的处理方法,这很混乱,没有任何好处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 2013-11-23
    • 2017-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多