如何解析带有&(等)字符错误的简单HTML DOM



关于SO有四到五个问题可以解决这个特定的问题(一个例子);然而,它们都相当老了(超过10年),没有一个能充分解决具体问题。我希望这个问题的答案可以解决我的具体问题,同时为社区澄清困惑。

我正试图解析客户的网站,为他们的IT部门建立当前内容的摘要。(请不要问我为什么他们不能自己做。)

在过去,我使用PHP简单HTML DOM解析器来完成这样的任务。我已经有七年没有使用这个库了,但是我从来没有遇到过这个问题。

当使用…将文档加载到对象时

$dom = new DOMDocument('1.0','UTF-8');
$dom->loadHTMLFile($url); // run WITH error output

PHP沿着这一行返回警告:

警告:DOMDocument::loadHTMLFile(): htmlParseEntityRef: expected/myScript/index.php中的';'在https://thehtmlfilename.html,第45行第47行

警告:DOMDocument::loadHTMLFile(): htmlParseEntityRef: no name inhttps://thehtmlfilename.html,行:88在/myScript/index.php上行47

这些警告似乎既不能阻止加载DOM,也不能阻止脚本运行。但是,当我尝试使用$anchors = $dom->getElementsByTagName('a');访问href组时,脚本将运行前三个或四个(构造良好的)href,然后遇到如下一行:

<li class="">
<a href="https://www.thecompany.com/campus_staff.html">Campus & Staff</a>
</li>
<li class="">
<a href="https://www.thecompany.com/parents-and-families.html">Family & Friends</a>
</li>

仔细分析可以确定,正是这些行产生了上面的警告。这两行都产生了"期待";警告。

当我var_dump$anchors对象时,返回的全部内容是:

object(DOMNodeList)#2 (1) {
["length"]=>
int(90)
}

其他答案,如上面的链接问题,提到

我最好的猜测是有一个未转义的& (&)在HTML的某个地方。这将使解析器认为我们在实体参考(例如©)。当它到达;时,它认为实体是结束了。然后它意识到它所拥有的并不符合实体,所以它发出警告并以纯文本形式返回内容。

这表明我在正确的轨道上。

建议的各种解决方案都规定将&更改为非&字符使用不同的方法:str_replace,pre_replace,htmlentities, &等

我明白这些答案有矛盾。&字符似乎中断了由loadHTMLFile()发起并创建DOM对象的加载过程。如果是这种情况,程序员无法在处理之前将&字符replace

如何呢?识别问题是向前迈出的一大步,就像在关联问题中一样;但是我们如何解决这个问题呢?我们如何从这个页面拉这些href链接?

值得注意的是,我们在…

中发现的&符号
<a href="https://www.thecompany.com/campus_staff.html">Campus & Staff</a>

…不是在href本身,而是在链接文本中(在<a>标签之间)。

首先以字符串形式获取内容,然后用可解析的内容替换&号实例。

$html = file_get_contents('/path/to/file.html');
$html = preg_replace('/&(?=s)/', '&amp;', $html);
$doc = new DOMDocument();
$doc->loadHTML($html);
$anchors = $doc->getElementsByTagName('a');
foreach ($anchors as $anchor) {
print $anchor->firstChild->wholeText;
}

相关内容

  • 没有找到相关文章

最新更新