XPath介绍
- XPath(XML Path Language,XML路径语言),是一门在XML文档中查找信息的语言。HTML与XML结构类似,也可以在HTML中查找信息。
XPath常用路径表达式
- XPath使用路径表达式来选取HTML文档中的节点或者节点集。这些路径表达式和我们在常规的计算机文件系统中看到的表达式非常相似。
- 例如,在Windows系统中,要指明桌面上的文件hello.py的路径,通常可以写成C:\Users\tao\Desktop\hello.py,从C盘开始,使用反斜杠()逐级向下查找,直到找到最终的目标。
安装lxml库
- 使用XPath之前,要先安装Python的lxml库。lxml库是一个HTML/XML的解析器。安装方法非常简单,在命令行中输入以下命令即可。
pip install lxml
导入lxml库
- 提取数据之前,要先导入lxml库的etree模块,再使用etree读取movies.html文件,生成一个节点数的对象,代码如下:
# 导入lxml库的etree模块
from lxml import etree
# 解析movies.html文件,返回一个节点树的对象
html_selector = etree.parse("movies.html",etree.HTMLParser())
- 节点树的对象生成后,就可以使用XPath抽取数据了。
获取html元素
- 使用反斜杠()从根节点开始获取html元素
# 获取根节点html的元素
root = html_selector.xpath("/html")
print(root)
- 运行结果如下:
[<Element html at 0x17b537de4c0>]
- 可以看出,返回的root是一个列表,列表中存储了一个Element(元素)类型的对象,对象中节点的名称为html。
获取title元素
- 可以使用斜杠(/)从根节点开始逐层查找元素的子节点。
# 斜杠(/)获取节点title
title = html_selector.xpath("/html/head/title")
print(title)
- 运行结果如下:
[<Element title at 0x29f2299d600>]
- 需要注意的是,斜杠(/)在起始位置时,代表的是从根节点开始查找,其他位置代表查找子节点。
获取title的文本
- 可以使用text()获取节点title中的文本。
# text()获取节点title的文本
title_name = html_selector.xpath("/html/head/title/text()")
print(title_name)
- 运行结果如下:
['电影排行']
获取所有电影名称
- 电影名称所在的p节点相对根节点很远,如果从根节点逐层开始往下查找,XPath的表达式就会很长,如/html/body/div/div/p/text()。使用双斜杆(//)可以不考虑位置,获取页面中所有符合规则的子孙节点。
movie_name = html_selector.xpath("//p/text()")
print(movie_name)
- 运行结果如下:
['1. 肖生克的救赎', '2. 霸王别姬']
- 代码使用了双斜杆(//)抽取出页面中所有节点p的文本。注意抽取处理的所有数据,均是保存在列表中的。
- 当然,双斜杆(//)也可以放在路径表达式的中间,代码如下:
name = html_selector.xpath("/html//div[@id='content']/h1/text()")
- 运行结果如下:
['1. 肖生克的救赎', '2. 霸王别姬']
获取网页的编码格式
- 有时要获取的信息保存在属性中。例如,页面的编码格式就是在meta标签的charset属性中。可以使用“@属性名”的方式获取属性值。
# 使用@获取属性的值
meta = html_selector.xpath("//meta/@charset")
print(meta)
- 运行结果如下:
['UTF-8']
- 在爬虫中,经常使用@href获取超链接。
获取div的id属性值
- 通过斜杠(/)或者双斜杆(//)可以查找子节点或子孙节点。那么如何通过子节点,查找父节点呢?可以用两点(…)来实现。
attr = html_selector.xpath("//h1/../@id")
print(attr)
运行结果如下:
['content']
- h1的后面是两点(…),即定位到h1的父节点
,再使用@id获取属性id的值。
XPath带谓语的路径表达式
- 有时需要查找某个特定的节点或包含某个指定值的节点,如获取属性id为content的div元素,或者获取p节点的文本等,如果使用XPath路径表达式,实现起来就比较困难,这时就需要用到谓语了。谓语被嵌套在方括号([])中,用于查找特定节点或指定值的节点。