【问题标题】:PHP preg_match_all matches 74 out of 100 matchesPHP preg_match_all 匹配 100 个匹配项中的 74 个
【发布时间】:2011-08-07 21:49:02
【问题描述】:

我正在开展一个项目,该项目涉及从主要搜索引擎中进行抓取(更具体地说,检查页面排名并查找相似页面)。使用 curl 我调用搜索引擎,然后使用单个 preg_match_all 我将所有结果放在一个数组中。我对 Google 和 Bing 没有任何问题,但是当我为 Yahoo 编写脚本时,它可以工作,但它有一个错误。

我正在荷兰测试“autobedrijf”。我在页面上有 100 个结果,但结果数组中只有 74 个结果。我将正则表达式复制到 this tool,插入了 Yahoo 的页面源,它​​匹配了所有 100 个结果。

这些是来自 Yahoo 的第一批结果:

但在我得到的数组中:

-ledensite

-首页

-Welkom bij autobedrijf Tolsma Exmorra

-等等。

这意味着在“主页”之后它会跳过 3 个结果。我试图找出结果 5 和 6 之间的任何差异(最后一个跳过和下一个),但我没有找到任何不匹配第 5 个的理由。

这是 preg_match_all 脚本:

$pattern = '@<div>\s*<h3>\s*<a[^<>]*\shref="([^*"]*\*\*)*([^<>]*)">
([^<>]*(<b>[^<>]*</b>)*[^<>]*(<wbr>)*[^<>]*)</a>\s*</h3>\s*</div>@siU';
preg_match_all($pattern, $result['EXE'], $matches);

这两个结果的 Yahoo 页面源如下所示:

<li><div class="res"><div><h3><a dirtyhref="http://nl.wrs.yahoo.com
/_ylt=A7x9Qb3rKqxN1XYA1PhzKAx.;_ylu=X3oDMTBydXF0bjc3BHNlYwNzcgR
wb3MDNQRjb2xvA2lyZAR2dGlkAw--/SIG=11n0lgcgp/EXP=1303157611/**http%3a
//www.autobedrijfgreijmans.nl/" class="yschttl spt" 
href="http://nl.wrs.yahoo.com/_ylt=A7x9Qb3rKqxN1XYA1PhzKAx.;
_ylu=X3oDMTBydXF0bjc3BHNlYwNzcgRwb3MDNQRjb2xvA2lyZAR2dGlkAw--/SIG
=11n0lgcgp/EXP=1303157611/**http%3a//www.autobedrijfgreijmans.nl/">
<b>Autobedrijf</b> Greijmans Weert - Toyota <wbr>Specialist Occasions 
APK</a></h3></div><div class="abstr">In het databestand van 
<b>Autobedrijf</b> Greijmans vindt u zeer eenvoudig tweedehands auto's, 
bedrijfswagens, klassiekers. Kijk snel op onze website</div><span 
class="url">www.<b>autobedrijfgreijmans.nl</b></span> - <a 
href="http://nl.wrs.yahoo.com/_ylt=A7x9Qb3rKqxN1XYA1fhzKAx./SIG=
186dh8afd/EXP=1303157611/**http%3a//74.6.239.67/search/cache%3fei=
UTF-8%26p=autobedrijf%26n=100%26va_vt=any%26vo_vt=any%26vp_vt
=any%26vst=0%26vf=all%26vm=p%26u=www.autobedrijfgreijmans.nl/
%26w=autobedrijf%26d=IxshPvbJWijU%26icp=1%26.intl=nl%26sig=yI6R7vJN31J
T92YKlVnT1g--">In de cache</a></div></li>

<li><div class="res"><div><h3><a dirtyhref="http://nl.wrs.yahoo.com
/_ylt=A7x9Qb3rKqxN1XYA1vhzKAx.;_ylu=X3oDMTBybWh0ZnN2BHNlYwNzcgRwb3MDNg
Rjb2xvA2lyZAR2dGlkAw--/SIG=11l17c21h/EXP=1303157611/**http%3a//www.
autobedrijf-tolsma.nl/" class="yschttl spt" href="http://www.autobedrijf
-tolsma.nl/">Welkom bij <b>autobedrijf</b> Tolsma Exmorra</a></h3></div>
<div class="abstr">Welkom op de vernieuwde website van <b>autobedrijf</b> 
Tolsma Exmorra incl.digitale showroom <b>...</b> Welkom bij <b>autobedrijf
</b> tolsma. Op deze site nodigen wij U uit een <b>...</b></div><span 
class="url">www.<b>autobedrijf-tolsma.nl</b></span> - <a href="http://nl.
wrs.yahoo.com/_ylt=A7x9Qb3rKqxN1XYA1_hzKAx./SIG=1840la9c5/EXP=1303157611/
**http%3a//74.6.239.67/search/cache%3fei=UTF-8%26p=autobedrijf%26n=100
%26va_vt=any%26vo_vt=any%26vp_vt=any%26vst=0%26vf=all%26vm=p%26u=
www.autobedrijf-tolsma.nl/%26w=autobedrijf%26d=YBZQIvbJWlDf%26icp=1%26.
intl=nl%26sig=zRU95PdBOTfII93dZ411ZA--">In de cache</a></div></li>

我已经坚持了 5 个多小时,我不明白为什么 正则表达式工具匹配两个结果,而 PHP 中的 preg_match_all 只匹配第二个结果强>。

如果重要的话 - 我正在使用 Apache 和 PHP 5.3.5 在 Windows 上进行测试。

欢迎任何建议,如果您有兴趣,我可以提供额外的示例和测试代码。

【问题讨论】:

  • 如果您使用正则表达式解析 html,那么您做错了。说真的,使用适当的解析库..
  • 我会尝试以“正确的方式”来做,但实际上,对于 Google 和 Bing 来说,它与正则表达式完美配合 :)

标签: php regex web-scraping preg-match-all


【解决方案1】:

一个未完成的起点:

<?php

$url = 'http://nl.search.yahoo.com/search?p=autobedrijf&toggle=1&cop=mss&ei=UTF-8&fr=yfp-t-732';

$html = file_get_contents($url);

$doc = new DOMDocument;
libxml_use_internal_errors(TRUE);
$doc->loadHTML($html);
libxml_use_internal_errors(FALSE);

$titles = $doc->getElementsByTagName('h3');
foreach($titles as $t){
    echo $t->nodeValue . PHP_EOL;
}

?>

【讨论】:

  • 非常感谢,我试试看。就我而言,正则表达式真的很让人头疼。
【解决方案2】:

我建议使用 Yahoo api。他们提供非常好的服务,可以使用雅虎查询语言从雅虎获得结果。 http://developer.yahoo.com/yql/

示例:

http://developer.yahoo.com/yql/console/#h=select%20*%20from%20search.web%20where%20query%3D%22autobedrijf%22

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 2013-02-21
    • 2014-04-08
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多