XPath简介
XPath 是一门在 XML 文档中查找信息的语言。XPath 用于在 XML 文档中通过元素和属性进行导航。
什么是XPath?
- XPath 使用路径表达式在 XML 文档中进行导航
- XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。
- XPath 包含一个标准函数库
- XPath 含有超过 100 个内建的函数。这些函数用于字符串值、数值、日期和时间比较、节点和 QName 处理、序列处理、逻辑值等等
- XPath 是 XSLT 中的主要元素
- XPath 是 XSLT 标准中的主要元素。如果没有 XPath 方面的知识,您就无法创建 XSLT 文档。
- XPath 是一个 W3C 标准
- XPath 于 1999 年 11 月 16 日 成为 W3C 标准。
XPath 被设计为供 XSLT、XPointer 以及其他 XML 解析软件使用。
- XPath 于 1999 年 11 月 16 日 成为 W3C 标准。
XPath节点:
在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档节点(或称为根节点)
具体介绍见W3school:W3school之XPath节点
XPath语法:
XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。
下表给出最有用的路径表达式:
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
具体实例及用法见:W3school之XPath语法
lxml简介
lxml是 Python 处理 xml 文档的一个库,速度快,易编程。
在lxml中,只有Element,Element有子Element,构成一棵树。具体关于Element属性介绍:lxml教程
实例:使用xpath提取丁香园论坛的回复内容。
实现代码:
import requests
from lxml import etree
from bs4 import BeautifulSoup as bs
def get_html():
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
}
url = 'http://www.dxy.cn/bbs/thread/626626'
try:
html = requests.get(url,headers = headers)
if html.status_code == 200:
return html.text
except:
pass
def get_item(html):
topic_con = etree.HTML(html)
#result = etree.tostring(topic_con)
#print(result.decode('utf-8'))
content = []
user_id = topic_con.xpath('//div[@class="auth"]/a/text()')
#print(user_id)
#content = topic_con.xpath('//td[@class="postbody"]/text()|//td[@class="postbody"]/a/text()')
for i in range(len(user_id)):
content_test = topic_con.xpath(f'//*[@id="post_{i+1}"]/table/tbody/tr/td[2]/div[2]/div/table/tbody/tr/td//text()')
content_test = "".join(content_test)
content.append(content_test.replace("\n","").replace("\t",""))
#print(len(content))
#print(len(fixed))
zipped = zip(user_id,content)
for i in zipped:
print(i)
def main():
html = get_html()
info = get_item(html)
if __name__ == '__main__':
main()
从代码中我们不难发现,xpath和昨天beautiful soup 总体框架都是类似的,只是在获取网页的时候xpath改用etree去解析。
注意:由于xpath爬取下来的网页数据以列表形式存放,所以当我们分别爬取下用户名和其发帖的内容的时候,是存放在两个不同的列表中,一开始我的xpath语句写的有问题,虽然完整的爬取了所需要的数据,但是content列表的len缺是11,这意味着我不能用zip函数将用户名和其发的帖子内容一一对应。最后在求助群里大佬,特别感谢大鹏哥的助攻,将我的xpath语句改了,最后成功匹配。
运行结果: