html - 使用 xpath 从格式不正确的页面解析 XML
问题描述
注意:在写这个问题时,我注意到有一个 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 是示意性的,因此应该正确解析它。不同的工具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 up
^
/tmp/geckodriver.html:172: parser error : Entity 'rarr' not defined
es <span class="Bump-link-symbol float-right text-normal text-gray-light">→
...
还有很多。似乎 github 页面的格式不正确,正如规范所要求的那样。我也试过xmlstarlet
xmlstarlet sel -t -v -m '//div[@class=Header]' /tmp/geckodriver.html
但结果是相似的。
当 HTML 格式不正确时,是否无法使用这些工具提取一些数据?
解决方案
curl $(curl -s "https://github.com/mozilla/geckodriver/releases/latest" --head | grep -i location | awk '{print $2}' | sed 's/\r//g') > /tmp/geckodriver.html
curl -L https://github.com/mozilla/geckodriver/releases/latest
然后,xmllint
接受一个--html
参数,以使用 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
推荐阅读
- java - 如何传递包含另一个 Parcelable 类列表的 Parcelable 类?
- python - “numpy.ndarray”对象没有属性“isin”
- c# - 使用 NHibernate 和 Oracle 将连接字符串更新到 LDAP
- json - 多个 Lottie 动画不自动播放
- office365 - Exchange 从 .csv 文件批量导入以从允许列表中删除,然后从允许列表中删除
- datetime - 访问查询的日期函数
- java - Spring Webflux如何在从存储库中接收最后一个元素后保持订阅状态
- python - 理解 Python - 变量在函数外部定义,但在函数内部更改而没有返回
- kotlin - 如何在 gradle 中扩展现有任务?
- node.js - 配置中缺少凭据,如果使用 AWS_CONFIG_FILE,请设置 AWS_SDK_LOAD_CONFIG=1 node.js