xpath
全称 XML Path Language 是一门在XML文档中 查找信息的语言 最初是用来搜寻XML文档的 但是它同样适用于HTML文档的搜索
XPath 的选择功能十分强大,它提供了非常简洁的路径选择表达式,另外还提供了超过100个内置函数,用于字符串,数值,时间的匹配 以及节点和序列的处理
XPath 于1999年11月16日成为W3C标准 被设计为供XSLT、XPointer、以及其它XML解析软件使用
常用节点选择工具 Chrome插件 XPath Helper(下载crx扩展程序进行安装)
xpath工作原理就是通过对hmtl代码标签以及属性和css样式的抓取获取相应数据,所以要使用xpath必须做到对html代码了解。
常用规则
nodename 选取此节点的所有子节点
/ 从当前节点选取直接子节点
// 从当前节点选取子孙节点
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
安装lxml
在终端
pipinstall lxml==4.5.0
实例
from lxml import etree #导入lxml的etree模块
text='''
- first item
- second item
- third item
- fourth item
- fifth item
'''
html = etree.HTML(text)#调用HTML类,初始化构造一个XPath解析对象
print(html) #
result = etree.tostring(html) #将HTML对象转为字节数组
print(result.decode('utf-8')) #解码输出字符串
print('*'*50)
'''
也可以获取本地的文件进行解析
'''
html1 = etree.parse('a.html',parser=etree.HTMLParser())
print(html) #
result1 = etree.tostring(html1)
print(result1.decode('utf-8'))
a.html:
Title1.1所有节点
一般会用//开头的XPath规则来选取所有符合要求的节点
例如:
from lxml import etree
html = etree.parse('a.html',etree.HTMLParser())
result1 = html.xpath('//*') #查找所有节点
print(result1)
*代表匹配所有节点 返回一个列表 每个元素是Element类型 其后是节点名
1.2指定节点
result2 = html.xpath('//li') #查找li元素所有节点
将html文档中所有的li标签查找出来
1.3子节点
通过/或者// 查找元素子节点或子孙节点
例如: 查找li节点的所有直接子节点a
result3 = html.xpath('//li/a') #查找li标签下的子节点a
print(result3)
查找li节点下所有子孙节点a
result4 = html.xpath('//li//a') #li标签下的所有a节点
print(result4)
1.4父节点
查找href="link4.html"的a标签的父节点的class值
result5 = html.xpath('//a[@href="link4.html"]/../@class')
print(result5) # ['item-1']
也可以通过parent:: 获取其父节点
# 查找href="link4.html"的a标签的所有父节点的class值,parent::*表示所有父节点,*可以替换指定标签
result5 = html.xpath('//a[@href="link4.html"]/parent::*/@class')
print(result5) # ['item-1']
1.5属性过滤
选取class为item-0 的li节点
result6 = html.xpath('//li[@class="item-1"]')
print(result6)
1.6文本获取
用xpath中text()方法获取节点中的文本
获取li节点中的文本
获取指定li标签下a标签的文本
e1 = html.xpath('//li[@class="item-1"]/a/text()') #返回list,['second item', 'fourth item']
print(e1)
获取指定li标签下所有的文本
e2 = html.xpath('//li[@class="item-0"]//text()')
print(e2)#返回三个结果
获取p标签中的文本
e3 = html.xpath('//p/text()')
print(e3)
1.7属性获取
获取指定li标签下所有a标签的href属性值
e4 = html.xpath('//li[@class="item-1"]/a/@href')
print(e4)
1.8属性多值
当一个标签有多个属性值时,怎么查找。
使用contains()函数:
包含任意一个属性即可匹配
text='''
first item'''
html = etree.HTML(text)
result = html.xpath('//li[contains(@class,"li")]/a/text()')
print(result)#返回结果是["first item"]
1.9多属性
有时需要匹配一个标签的多个属性时,采用运算符进行连接
text='''
first itemsecond item'''
html = etree.HTML(text)
result = html.xpath('//li[contains(@class,"li") and @name="item"]/a/text()')
print(result) #返回结果是["first item"]
1.10常见运行算符
查找多个元素标签
查找p标签和li标签
e4 = html.xpath('//p|//li')
1.11按序选择
有时候选择某些属性 可能同时匹配了多个节点 但是想要其中某个节点
如 第一个节点或者最后一个节点
'''排序'''
# 第一个li元素
e7 = html.xpath('//li[1]/a/@href')
print(e7) #['link1.html']
#最后一个li元素
e8 = html.xpath('//li[last()]/a/@href')
print(e8) #['link5.html']
#前两个li元素
e9 = html.xpath('//li[position()<3]/a/@href')
print(e9) #['link1.html', 'link2.html']
#倒数第三个
e10 = html.xpath('//li[last()-2]/a/@href')
print(e10)
1.12 节点轴选择
xpath提供了很多节点轴选择方法 包括子元素,兄弟元素,父元素,祖先元素等
'''节点轴选择'''
from lxml import etree
text='''
- 11first item
- second item
- third item
- fourth item
- fifth item
'''
html = etree.HTML(text)
result = html.xpath('//li[1]/ancestor::*')
print(result)# 获取第一个li所有祖先节点 包括html body div ul
result = html.xpath('//li[1]/ancestor::div')
print(result)#限定条件 div
result = html.xpath('//li[1]/attribute::*')
print(result)#获取所有属性值 返回li节点所有属性值
result = html.xpath('//li[1]/child::a[@href="link1.html"]')
print(result)#获取所有直接子节点 限定条件href = link1.html
result = html.xpath('//li[1]/descendant::span')
print(result)# 获取所有子孙节点 限定span节点 不包含a节点
result = html.xpath('//li[1]/following::*[2]/text()')
print(result)#获取当前节点之后的所有节点 虽然加了* 但又加了索引选择 只获取第二个后续节点
result = html.xpath('//li[1]/following-sibling::*')
print(result)#获取当前节点之后的所有同级节点
实战爬取百度校花吧
分析:
分析校花吧的url以及网页结构:
分析可得:我们要爬取的内容以及网页是分页显示的。