爬虫xpath无法定位tbody标签

53次阅读

共计 1930 个字符,预计需要花费 5 分钟才能阅读完成。

测试库:lxml 库;链接链接:http://www.sxchxx.com/index-13-1075-1.html

问题发现

个人比较喜欢用 xpath 解析网页,但时常得到的结果却是一个空列表。

1.1 etree.HTML

from lxml import etree
import requests

url = 'http://www.sxchxx.com/index-13-1075-1.html'

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36',
}
resposne = requests.get(url, headers=headers)

parser = etree.HTMLParser(encoding="utf-8")
html = etree.HTML(resposne.text, parser=parser)

resu=html.xpath('//*[@id="large_mid"]/table[2]/tr[3]/td/p//text()')
print(resu)

当用如上代码解析如下网页时,可以获取正文

但发现我们并没有在 rule 里面加入 tbody 标签。相反,加入 tbody 标签会使的解析结果变成一个空列表

html.xpath('//*[@id="large_mid"]/table[2]/tbody/tr[3]/td/p//text()') # 这样会得到空列表

1.2 etree.parse

使用 etree.parse 和 etree.HTML 恰好相反

from lxml import etree
import requests

parser = etree.HTMLParser(encoding="utf-8")
html = etree.parse('test.html', parser=parser)


content = html.xpath('//*[@id="large_mid"]/table[2]/tbody/tr[3]/td/p//text()')

print(content)

将网页保存成 test.html,再用 etree.parse 加载,发现 rule 中加入 tbody 标签才能获得预期的结果;不加 tbody 标签会获得一个空列表

1.3 代码对比

from lxml import etree
import requests

parser = etree.HTMLParser(encoding="utf-8")
html = etree.parse('test.html', parser=parser)

content = html.xpath('//*[@id="large_mid"]/table[2]/tbody/tr[3]/td/p//text()')
print(content)

print('---------------- 分割线 -------------------')

url = 'http://www.sxchxx.com/index-13-1075-1.html'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36',
}
resposne = requests.get(url, headers=headers)

parser = etree.HTMLParser(encoding="utf-8")
html = etree.HTML(resposne.text, parser=parser)

content = html.xpath('//*[@id="large_mid"]/table[2]/tr[3]/td/p//text()')
print(content)

解决问题

2.1 曲线救国

如果解析在线网页,不要添加 tbody 标签
反则解析本地 (离线) 网页,添加 tbody 标签

2.2 其他方法

请看下面的原因分析

问题发生的原因

对比上面两种方法,差异 在于
html = etree.parse('test.html', parser=parser)
html = etree.HTML(resposne.text)
这两行代码

而解析器是 相同 的 parser = etree.HTMLParser(encoding=”utf-8″)

因此,我猜测,可能是 parse 或者 HTML 对代码做了某种“格式化”调整

貌似 lxml 这个库使用其他语言编写,看不到源代码,无法从源代码下手检查

正文完
 0