遇到一个奇怪的问题,用 xpath 抓取这个网站 id 为'wc_channels'的 table 标签,会直接从 table 标签一直获取的 html 文件结尾

2022-04-10 18:17:38 +08:00
 tg11

代码如下

import ssl
from urllib import request
from lxml import etree


def urllibGet(url):
    # 取消全局证书验证
    ssl._create_default_https_context = ssl._create_unverified_context
    headers = {
        'Host': 'www.livesoccertv.com',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0',
    }
    res = request.Request(url=url, headers=headers)
    res = request.urlopen(res)
    return res.read().decode('utf-8')


res = urllibGet('https://www.livesoccertv.com/match/4027329/aston-villa-vs-tottenham-hotspur/')
html = etree.HTML(res)
channel_list = html.xpath('//table[@id="wc_channels"]')
html_str = etree.tostring(channel_list[0], encoding='utf-8').decode()
open('content.html', 'w').write(html_str)

是我哪里写错了吗?

2030 次点击
所在节点    Python
5 条回复
tg11
2022-04-10 18:32:13 +08:00
测试过其它网站了,这样写没有任何问题
phpfpm
2022-04-10 19:54:37 +08:00
标签没写好没闭合呗。。。
ec0
2022-04-10 19:59:22 +08:00
我这边复现了你的问题
于是我 ctrl+u 看了一下这个网页的源代码,发现这个网页的第一句是
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

而一般网页(比如 V2EX )是 <!DOCTYPE html>
于是我跳过了这个注释,就能够正常获取 table 了

也就是把 html = etree.HTML(res) 改成
html = etree.HTML(res[121:])

121 是 DOCTYPE 的长度
tg11
2022-04-10 23:30:45 +08:00
@ec0 我靠。。这问题打死我也想不到。。感谢大佬了
Kobayashi
2022-04-19 11:53:49 +08:00
应该就是 HTML 文件不符合规范。可以在 tostring 时正确截断: etree.tostring(method='xml')

建议直接使用 html 而不是 etree 。from lxml import html, html.fromstring(), html.tostring()。

不确定有没有办法在 parse 时搞定,上面方法应该是在输出时作了校验。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/846110

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX