PHP使用curl进行网页抓取 - 我该如何调试?

3
我几个小时前才学会了scrapping和cUrl,从那时起,我就一直在尝试使用它。然而,现在我遇到了一些奇怪的问题。下面的代码可以在一些站点上正常工作,而在其他站点上则无法正常工作(当然,我修改了url和xpath...)。请注意,在测试curl_exec是否已经正确执行时没有引发任何错误。所以问题必须来自于之后的某个地方。我的一些问题如下:
  1. 如何检查新的DOMDocument是否已经正确创建:if(??)
  2. 如何检查新的DOMDocument是否已经正确填充了html内容?
  3. ......是否已经创建了新的DOMXPath对象?
希望我表述清楚。非常感谢您的回复。祝您好运。马克
我的php代码:
<?php
$target_url = "http://www.somesite.com";
$userAgent = 'Googlebot/2.1 (http://www.googlebot.com/bot.html)';

// make the cURL request to $target_url
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_URL,$target_url);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$html= curl_exec($ch);

if (!$html) {
    echo "<br />cURL error number:" .curl_errno($ch);
    echo "<br />cURL error:" . curl_error($ch);
    exit;
}

// parse the html into a DOMDocument
$dom = new DOMDocument();
@$dom->loadHTML($html);

// grab all the on the page
$xpath = new DOMXPath($dom);
$hrefs = $xpath->query('somepath');

for ($i = 0; $i < $hrefs->length; $i++) {
    $href = $hrefs->item($i);
    $url = $href->getAttribute('href');
    echo "<br />Link: $url";
}

?>

+1 不要使用正则表达式来“解析”HTML。为了检测错误,请检查 DOMDocument::loadHTML() 的相应返回值,并可能移除抑制运算符 @ - Linus Kleen
你好,Linus。感谢你的帮助。你能帮我看一下语法吗?应该是这样写:if( DOMDocument::loadHTML($html) {}else{} )吗? - Marc
你还可以通过在“did-curl-execute”检查后探测HTTP响应代码(这是通过curl_getinfo()和使用CURLINFO_HTTP_CODE实现)来扩展您的检查。 - Linus Kleen
无论是我的代码能够正常工作的网站还是不能正常工作的网站,curl_getinfo() 都会返回代码 200,表示一切正常。因此问题出在其他地方。这让我开始有点疯狂了... - Marc
@LinusKleen - 在curl执行后将其回显并检查HTML源代码,似乎在每行之间都有一个小的“段落图标”(请参见我在主贴中所做的编辑)。您认为这可能是原因吗? - Marc
2个回答

2

使用try/catch来检查文档对象是否创建,然后检查loadHTML()的返回值来确定HTML是否加载到文档中。您也可以在XPath对象上使用try/catch。

try
{
    $dom = new DOMDocument();

    $loaded = $dom->loadHTML($html);

    if($loaded)
    {
        // loaded OK
    }
    else
    {
        // could not load HTML
    }
}
catch(Exception $e)
{
    // document could not be created, see $e->getMessage()
}

在将HTML加载到DOMDocument之前,先打印出来,检查HTML是否正确,并且是你要找的页面,内容是否正确。如果服务器检测到它是一个机器人/脚本,你可能会被重定向或显示错误页面。不同的网站将具有不同的HTML结构,因此你需要相应地更改查询,除非你正在寻找像“title”这样非常通用的东西。 - MrCode
在写这篇文章之前,我已经检查过了。如果我回显 $html,它会正常显示...当你说网站有不同的 HTML 结构时,我需要寻找什么? - Marc
你想从HTML中提取什么样的数据? - MrCode
你可以尝试使用正则表达式删除这些,例如 $html = preg_replace('~>\s+<~', '><',$html); 看看是否有所不同。 - MrCode
你试过我发布的正则表达式来去除空格了吗? - MrCode
显示剩余8条评论

0
问题已解决。错误来自于Firebug给出了错误的路径。非常感谢MrCode的支持...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接