在非对象上调用成员函数getElementsByTagName(),为什么?

时间:2014-04-28 17:54:38

标签: php dom xpath domdocument

我写了这段代码:

function GetIds($forum_id,$from_page,$to_page) {
$ids = array();
$dom = new DOMDocument();
libxml_use_internal_errors(true);
for($i = $from_page; $i <= $to_page; $i++){
    $dom->loadHTMLFile('http://www.example.com/forumdisplay.php?page='.$i.'&f='.$forum_id);
        //$xpath = new DOMXPath($dom);
        //$items = $xpath->query('//ul[@id="threads"]/li[@id]');
    $items = $dom->getElementById('threads')->getElementsByTagName('li');
    foreach($items as $thread) {
    if(($id = substr($thread->getAttribute('id'), 7)) !== false)
    $ids[] = $id;
    }
}
    return $ids;
}

从这个论坛获取所有线程ID,使用示例:

$tids = GetIds("67",1,2); //Get all the Ids from page 1 to 2.
foreach($tids as $data) {
$file = fopen("threads.txt", "a+");
fwrite($file, "{$data}:");
fclose($file);
}

当我运行代码时,我收到此错误: 在第145行的C:\ wamp \ www \ eProject \ functions.PHP中的非对象上调用成员函数getElementsByTagName()

第145行:

$items = $dom->getElementById('threads')->getElementsByTagName('li');

有什么问题?

2 个答案:

答案 0 :(得分:0)

这是因为重定向。

http://www.example.com/forumdisplay.php?page=1f=67

评估为

http://www.example.com/forumdisplay.php?f=67

因此在第一个网址提取

$items = $dom->getElementById('threads')

返回NULL而不是相关对象。

您应该引用静态网址,同时为测试目的打开警告错误


当深入研究问题时,我意识到给定的目标站点可能已开始使用Incapsula以防止DDoS攻击,从而阻止不必要的请求。

在这种情况下,目标期望某些标头,以便允许请求。

不幸的是,我无法提供该网站所期望的确切信息,也许您应该检查它。

我发现了一个关于使用Incapsula的网站可能会有什么期望的讨论:http://myanimelist.net/forum/?topicid=685567&show=20

答案 1 :(得分:0)

直接提取URL并不直接返回所需内容(h / t RoyalBg)。这不是您的代码的问题 - 它产生的请求没有任何错误,它应该正确处理所返回的内容所需的内容。

您尝试抓取的网站似乎不再允许以脚本尝试访问页面的方式直接访问页面。该站点现在将一个脚本提供给浏览器(其中一些被混淆),显然处理加载内容。

解决方案是编写额外的代码来处理脚本并正确地要求服务器向您发送所需的内容。我的直觉是,改变的一个目的可能是防止他们的网站被刮掉。如果是这样的话,那么这个脚本中断很可能是从现在开始一直出现的情况。