升级到 PHP8.1 后出现“使用 DOMDocument 和 cURL 的通用 DOM 抓取工具”错误

'Generic DOM scraper using DOMDocument and cURL' error after upgrading to PHP8.1

提问人:Emiel 提问时间:4/26/2023 更新时间:4/26/2023 访问量:35

问:

我已经使用 DOM 抓取器代码好几年了(我不记得我从哪里得到它了)。 从 PHP7.4 升级到 PHP8.1(最终)后,它停止工作,并出现以下错误代码:

DOMDocument::loadHTML(): Argument #1 ($source) must not be empty

在我看来,变量永远不会为空。我在 Joomla 3.10、Apache、Linux 中的一个模块中运行此代码。我也在另一个文件中使用相同的代码,该文件是使用 cronjob 从 CLI 运行的(出于不同的目的)。这似乎工作得很好。但是从浏览器运行,它似乎不再起作用了。 这里有什么问题?我该如何解决?这是抓取代码:

// acquire data
$source = 'https://www.somesite.com/category/somepage';
$scraper = new DOMScraper();
$scraper->setSite($source)->setSource();
echo $scraper->getInnerHTML('table');

/**
 * Generic DOM scraper using DOMDocument and cURL
 */
Class DOMScraper extends DOMDocument{
    public $site;
    private $source;
    private $dom;

    function __construct(){
        libxml_use_internal_errors(true);
        $this->preserveWhiteSpace = false;
        $this->strictErrorChecking = false;
    }

    function setSite($site){
        $this->site = $site;
        return $this;
    }

    function setSource(){
        if(empty($this->site))return 'Error: Missing $this->site, use setSite() first';
        $this->source = $this->get_data($this->site);
        return $this;
    }

    function getInnerHTML($tag, $id=null, $nodeValue = false){
        if(empty($this->site))return 'Error: Missing $this->source, use setSource() first';
        $this->loadHTML($this->source);
        $tmp = $this->getElementsByTagName($tag);
        $ret = null;
        foreach ($tmp as $v){
            if($id !== null){
                $attr = explode('=',$id);
                if($v->getAttribute($attr[0])==$attr[1]){
                    if($nodeValue == true){
                        $ret .= trim($v->nodeValue);
                    }else{
                        $ret .= $this->innerHTML($v);
                    }
                }
            }else{
                if($nodeValue == true){
                    $ret .= trim($v->nodeValue);
                }else{
                    $ret .= $this->innerHTML($v);
                }
            }
        }
        return $ret;
    }

    function innerHTML($dom){
        $ret = "";
        $nodes = $dom->childNodes;
        foreach($nodes as $v){
            $tmp = new DOMDocument();
            $tmp->appendChild($tmp->importNode($v, true));
            $ret .= trim($tmp->saveHTML());
        }
        return $ret;
    }

    function get_data($url){
        if(function_exists('curl_init')){
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 5);
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $data = curl_exec($ch);
            curl_close($ch);
            return $data;
        }else{
            return file_get_contents($url);
        }
    }
}
PHP 变量 curl dom

评论

0赞 Chris Haas 4/26/2023
第一行出现错误,应该是getInnerHTMLif(empty($this->source))
0赞 Emiel 4/27/2023
确实,你是对的。从来没有注意到这一点。致命错误现在消失了,脚本可以在 php 8 下运行。

答: 暂无答案