使用 xpath 从格式不正确的页面解析 XML

Posted

技术标签:

【中文标题】使用 xpath 从格式不正确的页面解析 XML【英文标题】:Parse XML from not well formed page using xpath 【发布时间】:2020-09-24 12:51:46 【问题描述】:

通知: 在写这个问题时,我注意到有一个 Github API 可以在没有 html 解析的情况下解决我的问题:https://api.github.com/repos/mozilla/geckodriver/releases/latest 我决定还是问它,因为我已经测试过如何解决所描述的解析格式错误的 HTML 本身的问题。所以请不要反对,因为它有一个 github API!我们可以用任何其他抛出验证错误的页面替换 github。

我想下载最新版的geckodriver。通过获取最新标签的重定向目标,我在发布页面上

curl $(curl -s "https://github.com/mozilla/geckodriver/releases/latest" --head | grep -i location | awk 'print $2' | sed 's/\r//g') > /tmp/geckodriver.html

带有geckodriver-vx.xxx-linux64.tar.gz 的第一个资产是必需的链接。由于 XML 是示意性的,因此应该正确解析它。 Different tools like xmllint 可以使用 xpaths 解析它。由于 xpath 对我来说是新的,所以我在标题上尝试了一个简单的查询。但是xmllint会抛出很多错误:

$ xmllint --xpath '//div[@class=Header]' /tmp/geckodriver.html
/tmp/geckodriver.html:51: parser error : Specification mandate value for attribute data-pjax-transient
  <meta name="selected-link" value="repo_releases" data-pjax-transient>
                                                                      ^
/tmp/geckodriver.html:107: parser error : Opening and ending tag mismatch: link line 105 and head
  </head>
         ^
/tmp/geckodriver.html:145: parser error : Entity 'nbsp' not defined
                Sign&nbsp;up
                          ^
/tmp/geckodriver.html:172: parser error : Entity 'rarr' not defined
es <span class="Bump-link-symbol float-right text-normal text-gray-light">&rarr;
...

还有很多。似乎 github 页面的格式不正确,正如规范所要求的那样。我也试过xmlstarlet

xmlstarlet sel -t -v -m '//div[@class=Header]' /tmp/geckodriver.html

但结果相似。

当 HTML 格式不正确时,是否无法使用这些工具提取一些数据?

【问题讨论】:

因此,xmllintxmlstarlet 在格式错误的 XML 内容上引发错误是完全有效的。 但是我没有从提供的选择器中得到任何输出。我希望获得选定的 HTML 元素,并且需要一些不打印这些错误的 silent 模式。 【参考方案1】:

curl $(curl -s "https://github.com/mozilla/geckodriver/releases/latest" --head | grep -i location | awk 'print $2' | sed 's/\r//g') &gt; /tmp/geckodriver.html

use -L, and have curl follow the redirection可能更简单:

curl -L https://github.com/mozilla/geckodriver/releases/latest

然后,xmllintaccepts an --html argument,使用 HTML 解析器:

xmllint --html --xpath '//div[@class=Header]'

但是,这与该页面上的任何内容都不匹配,因此您可能希望将 XPath 基于以下内容:

'string((//a[span[contains(.,"linux")]])[1]/@href)'

产量:

/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux32.tar.gz

【讨论】:

以上是关于使用 xpath 从格式不正确的页面解析 XML的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 XPATH 从 XML 中解析和获取准确的结果

解析 html -> xml 并使用 Xpath 进行查询

xml 解析错误:python 中格式不正确<invalid token>

通过 XPath 解析 HTML [关闭]

XML 解析错误:在 FireFox 中格式不正确,但在 Chrome 中格式良好

200分求解:dom4j 使用XPATH解析。。诡异的问题