本文同步发表于个人微信公众号,扫一扫文章底部的二维码或在微信搜索 极客导航 便可关注,每一个工做日都有文章更新。html
前两篇咱们把网络库Requests大概的用法学了一遍,把网站上的每页数据请求下来是爬虫的第一步,接下来咱们就须要把每页上对咱们有用数据进行提取。提取数据的方式有不少,好比说正则、xpath、bs4等,咱们今天就来学一下xpath的语法。python
数据格式 | 描述 | 做用 |
---|---|---|
XML | 可扩展标记语言 | 用来传输和存储数据 |
HTML | 超文本标记语言 | 用来显示数据 |
pip3 install lxml
复制代码
XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和咱们在常规的电脑文件系统中看到的表达式很是类似。浏览器
表达式 | 含义 |
---|---|
/ | 从根节点开始 |
// | 从任意节点 |
. | 从当前节点 |
.. | 从当前节点的父节点 |
@ | 选取属性 |
text() | 选取文本 |
案例微信
from lxml import etree
data = """ <div> <ul> <li class="item-0"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><a href="link3.html">third item</a></li> <li class="item-1" id="1" ><a href="link4.html">fourth item</a></li> <li class="item-0" data="2"><a href="link5.html">fifth item</a> </ul> </div> """
html = etree.HTML(data)#构造了一个XPath解析对象。etree.HTML模块能够自动修正HTML文本。
li_list = html.xpath('//ul/li')#选取ul下面的全部li节点
#li_list = html.xpath('//div/ul/li')#选取ul下面的全部li节点
a_list = html.xpath('//ul/li/a')#选取ul下面的全部a节点
herf_list = html.xpath('//ul/li/a/@href')#选取ul下面的全部a节点的属性herf的值
text_list = html.xpath('//ul/li/a/text()')#选取ul下面的全部a节点的值
print(li_list)
print(a_list)
print(herf_list)
print(text_list)
#打印
[<Element li at 0x1015f4c48>, <Element li at 0x1015f4c08>, <Element li at 0x1015f4d08>, <Element li at 0x1015f4d48>, <Element li at 0x1015f4d88>]
[<Element a at 0x1015f4dc8>, <Element a at 0x1015f4e08>, <Element a at 0x1015f4e48>, <Element a at 0x1015f4e88>, <Element a at 0x1015f4ec8>]
['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']
['first item', 'second item', 'third item', 'fourth item', 'fifth item']
复制代码
咱们发现最后打印的值都是一个列表对象,若是想取值就能够遍历列表了。网络
选取未知节点 XPath 通配符可用来选取未知的 XML 元素。函数
通配符 | 含义 |
---|---|
* | 选取任何元素节点 |
@* | 选取任何属性的节点 |
案例学习
from lxml import etree
data = """ <div> <ul> <li class="item-0"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><a href="link3.html">third item</a></li> <li class="item-1" id="1" ><a href="link4.html">fourth item</a></li> <li class="item-0" data="2"><a href="link5.html">fifth item</a> </ul> </div> """
html = etree.HTML(data)
li_list = html.xpath('//li[@class="item-0"]')#选取class为item-0的li标签
text_list = html.xpath('//li[@class="item-0"]/a/text()')#选取class为item-0的li标签 下面a标签的值
li1_list = html.xpath('//li[@id="1"]')#选取id属性为1的li标签
li2_list = html.xpath('//li[@data="2"]')#选取data属性为2的li标签
print(li_list)
print(text_list)
print(li1_list)
print(li2_list)
#打印
[<Element li at 0x101dd4cc8>, <Element li at 0x101dd4c88>]
['first item', 'fifth item']
[<Element li at 0x101dd4d88>]
[<Element li at 0x101dd4c88>]
复制代码
谓语的一些路径表达式网站
表达式 | 含义 |
---|---|
[?] | 选取第几个节点 |
last() | 选取最后一个节点 |
last()-1 | 选取倒数第二个节点 |
position()-1 | 选取前两个 |
案例spa
from lxml import etree
data = """ <div> <ul> <li class="item-0"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><a href="link3.html">third item</a></li> <li class="item-1" id="1" ><a href="link4.html">fourth item</a></li> <li class="item-0" data="2"><a href="link5.html">fifth item</a> </ul> </div> """
html = etree.HTML(data)
li_list = html.xpath('//ul/li[1]') # 选取ul下面的第一个li节点
li1_list = html.xpath('//ul/li[last()]') # 选取ul下面的最后一个li节点
li2_list = html.xpath('//ul/li[last()-1]') # 选取ul下面的最后一个li节点
li3_list = html.xpath('//ul/li[position()<= 3]') # 选取ul下面前3个标签
text_list = html.xpath('//ul/li[position()<= 3]/a/@href') # 选取ul下面前3个标签的里面的a标签里面的href的值
print(li_list)
print(li1_list)
print(li2_list)
print(li3_list)
print(text_list)
#打印
[<Element li at 0x1015d3cc8>]
[<Element li at 0x1015d3c88>]
[<Element li at 0x1015d3d88>]
[<Element li at 0x1015d3cc8>, <Element li at 0x1015d3dc8>, <Element li at 0x1015d3e08>]
['link1.html', 'link2.html', 'link3.html']
复制代码
表达式 | 含义 |
---|---|
starts-with | 选取以什么开头的元素 |
contains | 选取包含一些信息的元素 |
and | 而且的关系 |
or | 或者的关系 |
案例插件
from lxml import etree
data = """ <div> <ul> <li class="item-0"><a href="link1.html">first item</a></li> <li class="item-1"><a href="link2.html">second item</a></li> <li class="item-inactive"><a href="link3.html">third item</a></li> <li class="item-1" id="1" ><a href="link4.html">fourth item</a></li> <li class="item-0" data="2"><a href="link5.html">fifth item</a> </ul> </div> """
html = etree.HTML(data)
li_list = html.xpath('//li[starts-with(@class,"item-1")]')#获取class包含以item-1开头的li标签
li1_list = html.xpath('//li[contains(@class,"item-1")]')#获取class包含item的li标签
li2_list = html.xpath('//li[contains(@class,"item-0") and contains(@data,"2")]')#获取class为item-0而且data为2的li标签
li3_list = html.xpath('//li[contains(@class,"item-1") or contains(@data,"2")]')#获取class为item-1或者data为2的li标签
print(li_list)
print(li1_list)
print(li2_list)
print(li3_list)
#打印
[<Element li at 0x101dcac08>, <Element li at 0x101dcabc8>]
[<Element li at 0x101dcac08>, <Element li at 0x101dcabc8>]
[<Element li at 0x101dcacc8>]
[<Element li at 0x101dcac08>, <Element li at 0x101dcabc8>, <Element li at 0x101dcacc8>]
复制代码
以上是Xpath一些经常使用用法,若是想了解更多的语法能够参考W3School
咱们能够在浏览器安装一些xpath插件,方便咱们进行解析数据。
去浏览器扩展下载这些插件,会在浏览器左上角看到图标,以下
咱们把网络库、解析库,接下来咱们就能够开始真正的爬虫之旅,后续的文章打算用Requests和Xpath爬取几个网站。
欢迎关注个人公众号,咱们一块儿学习。