无法从网站上抓取内容

| 我正在尝试从网站上抓取一些内容,但是下面的代码不起作用(未显示任何输出)。 这是代码
$url=\"some url\";
$otherHeaders=\"\";   //here i am using some other headers like content-type,userAgent,etc
some curl to get the webpage
...
..
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$content=curl_exec($ch);curl_close($ch);

$page=new DOMDocument();
$xpath=new DOMXPath($page); 
$content=getXHTML($content);  //this is a tidy function to convert bad html to xhtml 
$page->loadHTML($content);    // its okay till here when i echo $page->saveHTML the page is displayed

$path1=\"//body/table[4]/tbody/tr[3]/td[4]\";
$path2=\"//body/table[4]/tbody/tr[1]/td[4]\";

$item1=$xpath->query($path1);
$item2=$xpath->query($path2);

echo $item1->length;      //this shows zero 
echo $item2->length;      //this shows zero

foreach($item1 as $t)
echo $t->nodeValue;    //doesnt show anything
foreach($item2 as $p)
echo $p->nodeValue;    //doesnt show anything
我确定上面的
xpath
代码有问题。
xpaths
是正确的。我已经用
FirePath (a firefox addon)
检查了上面的ѭ2checked。我知道我在这里错过了一些非常愚蠢的东西,但是我看不出来。请帮忙。 我已经检查了相似的代码来抓取来自
Wikipedia
的链接(肯定是
xpaths
是不同的),并且效果很好。 所以我不明白为什么上面的代码不适用于其他
URLs
。我正在用
Tidy
清理
HTML
内容,所以我不认为xpath无法正确处理HTML是没有问题的吗? 我已经检查了
$item1=$xpath->query($path1)
之后的
nodelist
的长度,即
0
,这意味着
$xpath->query
出了问题,因为
xpaths
是正确的,因为我已经检查了
FirePath
我已经指出了一些修改代码,并使用
loadXML
代替
loadHTML
。 但这给我的错误是
Entity \'nbsp\' not defined in Entity
,因此我使用了
libxml
选项
LIBXML_NOENT
来替代实体,但错误仍然存​​在。     
已邀请:
        是的,您缺少了一些非常基本的东西:它是XHTML,因此必须注册(并使用!)正确的名称空间,然后才能期望得到结果。
$xpath->registerNamespace(\'x\', \'http://www.w3.org/1999/xhtml\');

$path1=\"//x:body/x:table[4]/x:tbody/x:tr[3]/x:td[4]\";
$path2=\"//x:body/x:table[4]/x:tbody/x:tr[1]/x:td[4]\";

$item1=$xpath->query($path1);
$item2=$xpath->query($path2);
    
        看来问题出在某种程度上与XPath和名称空间有关。 PHP手册显示了一个有趣的用户评论   如果您已经注册了名称空间,   将您的XHTML等加载到您的   XPath \的DOMDocument对象和   仍然无法正常工作,   检查以确保您没有使用过   DOMDocument的loadHTML()或   loadHTMLFile()函数。对于XHTML   始终使用XML版本,   否则,您的XPath将永远不会   工作。 您的代码使用
loadHTML()
$content=getXHTML($content);  //this is a tidy function to convert bad html to xhtml 
$page->loadHTML($content);    // its okay till here when i echo $page->saveHTML the page is displayed
HTML不支持名称空间,因此即使原始文档(或Tidy输出的XHTML)具有名称空间,“ 22”也可能不会在文档对象的元素上设置名称空间。 因为您使用Tidy将文档转换为XHTML,所以我想您可以安全地使用
loadXML()
,而不会遇到解析错误。请注意,这将要求输入格式正确的XML。另外,它可能不知道HTML预定义的实体(例如ѭ26),如果是这种情况,则无法用正确的字符值替换实体。如果出现此类问题,请尝试为
loadXML()
设置不同的选项。     
        我听说FireFox添加了
tbody
元素(如果不存在)。 除了@Tomalak的建议外,或尝试使用不带
/tbody
位置步骤的XPath表达式。 另外,使用另一个工具作为XPath Visualizer来构造正确的XPath表达式,并立即查看它们在选择什么。     
        这个问题使我想起,解决问题的很多时间在于简单而不是复杂。我正在尝试
namespaces
error corrections
等,但是解决方案只要求仔细检查代码。 我的代码的问题是
loadHTML()
xpath initialization
的顺序。最初的顺序是
$xpath=new DOMXPath($page);
$page->loadHTML($content);
通过这样做,我实际上是在一个空文档上初始化ѭ35。现在通过先向
dom
加载
html
,然后初始化
xpath
,便可以颠倒顺序,这样我就能获得所需的结果。还建议通过从
xpath
中删除ѭ28lement元素作为
firefox
自动插入。所以正确的
xpath
应该是
$path1=\"//body/table[4]/tr[3]/td[4]\";
$path2=\"//body/table[4]/tr[1]/td[4]\";
感谢大家的建议和支持。     
        (请结合其他答案尝试以下内容,因为它们可能是其他警告。) 如果您的XPath无法正常工作,请尝试仅应用其中的一部分,以确保您确实遵循正确的路径。因此,请执行以下操作:
$path1=\"//body\";
$item1 = $xpath->query($path1);

foreach ($item1 as $t) {
    // to see the full XML of the returned node, as the nodeValue may be empty
    echo $t->ownerDocument->saveXML($t); 
}
然后继续将XPath增加到所需的位置。 另外,如果您发现节点的nodeValue和textContent为空,则应确保以正确的编码加载到DOMDocument中(例如,如果cURL响应返回UTF-8,则需要传递\'构造DOMDOcument时,将UTF-8作为第二个参数)。     

要回复问题请先登录注册