DOMDocument::loadHTML(): 由于输入错误,输入转换失败

Posted

技术标签:

【中文标题】DOMDocument::loadHTML(): 由于输入错误,输入转换失败【英文标题】:DOMDocument::loadHTML(): input conversion failed due to input error 【发布时间】:2014-06-15 03:23:57 【问题描述】:

我希望使用 PHPCURL 废弃一个中文网站。早些时候,我遇到了压缩结果的问题,SO 帮助我解决了这个问题。 现在我在通过 PHP - DOMDocument 解析内容时遇到了麻烦。 报错如下,

Warning: DOMDocument::loadhtml(): input conversion failed due to input error, bytes 0xE3 0x80 0x90 0xE8 in /var/www/html/ ..

即使警告这会阻止获得进一步的结果。

我的代码如下:

$agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0';
$curl = curl_init(); 
curl_setopt($curl, CURLOPT_URL,$url); 
curl_setopt($curl, CURLOPT_HTTPHEADER, array('text/html; charset=gb2312')); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);  
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_ENCODING, "");  // handling all compressions 
curl_setopt($curl, CURLOPT_USERAGENT, $agent);
curl_setopt($curl, CURLOPT_TIMEOUT, 1000);
$html = curl_exec($curl) or die("error: ".curl_error($curl));
curl_close($curl);
$htmlParsed = mb_convert_encoding($result,'utf-8','gb2312');

$doc = new DOMDocument();
$doc->loadHTML($htmlParsed);

$xpath = new DOMXpath($doc);

$elements = $xpath->query('//div[@class="test"]//a/@href');

if (!is_null($elements)) 
  foreach ($elements as $element) 
    echo "<br/>[". $element->nodeName. "]";

    $nodes = $element->childNodes;
    foreach ($nodes as $node) 
      echo $node->nodeValue. "\n";
    
  

我在目标网站中找到的内容类型为 ,

<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />

所以我尝试将结果转换为 utf-8。

由于在代码的“DOMDocument::loadHTML()”行输入转换失败,我无法解析网页以获取结果。 我目前被困在这一点上,任何帮助或建议将不胜感激。提前谢谢。

(之前我使用简单的 HTML DOM 解析器,这非常简单。但后来在阅读了 SO 中关于其用法的缺点后,我打算切换到 php 的原生 DOM 解析器)

【问题讨论】:

在加载 HTML 时尝试抑制错误,即@$doc-&gt;loadHTML($htmlParsed);,这可能是唯一可以接受抑制错误的情况,因为 PHP DOM 非常非常挑剔,尽量不要转换页面,按原样加载,然后尝试消除下一个问题(如果有)。 是的,我曾尝试抑制错误,但无法产生结果。 检查您的XPath 查询,尝试获得一些非常简单的内容,然后继续下一个元素。 @bodi0 是的,我尝试了一些非常简单的标签。但没有运气。! :( 了解这个 (bugs.php.net/bug.php?id=47108&edit=3) PHP 错误,您使用哪个版本的 PHP?而且,你可以试试 PHP tidy (php.net/manual/en/intro.tidy.php) 【参考方案1】:
<?php
$contents = file_get_contents('xml.xml');
function convert_utf8( $string )  
    if ( strlen(utf8_decode($string)) == strlen($string) )    
        // $string is not UTF-8
        return iconv("ISO-8859-1", "UTF-8", $string);
     else 
        // already UTF-8
        return $string;
    


$contents = mb_convert_encoding( $contents, mb_detect_encoding($contents), "UTF-8");

$xml = simplexml_load_string(convert_utf8($contents));
print_r($xml);

【讨论】:

【参考方案2】:

我今天看到了解决方案。

$html=new DOMDocument();  
$html_source    = get_html();
$html_source    =mb_convert_encoding( $html_source, "HTML-ENTITIES", "UTF-8");
$html->loadHTML( $html_source );

【讨论】:

【参考方案3】:

没有看到您正在解析的文档的完整标题,我只能猜测,但如果带有字符编码数据的 没有直接出现在标记之后,您可能会遇到 DomDocument 使用其默认值的情况ISO-8859-1 并遇到了【字符(gb2312 中的前三个“无效”字节),其中 0x80 字节将是无意义的第一位,因为这是 ISO-8859-1 中未使用的代码点。这可能会触发上面 cmets 中讨论的 DomDocument 中的错误。如果元素包含在内容类型元信息之前,则很容易发生这种情况。

我能想到的唯一尝试是通过一些准备来运行 html,并将该内容类型元标记移动到标记之后,以尝试使其使用正确的字符集。如果您使用 mb_convert_encoding 或 iconv 将编码转换为 iso-5589-1 或 utf-8,请确保修改元信息,因为不幸的是,DomDocument 在许多方面都很脆弱。

【讨论】:

以上是关于DOMDocument::loadHTML(): 由于输入错误,输入转换失败的主要内容,如果未能解决你的问题,请参考以下文章

PHP DOMDocument loadHTML 错误

DOMDocument::loadHTML(): 由于输入错误,输入转换失败

使用 php 从 html 文件中计算 li 项