前言
xpath在Python的爬虫学习中,起着举足轻重的地位,对比正则表达式 re两者可以完成同样的工作,实现的功能也差不多,但xpath明显比re具有优势,在网页分析上使re退居二线。
提示:以下是本篇文章正文内容,下面案例可供参考
一、安装?
pip install lxml
二、使用步骤
1.基本使用
from lxml import etree
selector=etree.HTML(源码) #将源码转化为能被XPath匹配的格式
selector.xpath(表达式) #返回为一列表
表达式 | 描述 | 实例 | 解析 |
---|---|---|---|
/ | 从根节点选取 | /body/div[1] | 选取根结点下的body下的第一个div标签 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 | //a | 选取文档中所有的a标签 |
./ | 当前节点再次进行xpath | ./a | 选取当前节点下的所有a标签 |
@ | 选取属性 | //@calss | 选取所有的class属性 |
【2】谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
路径表达式 | 结果 |
---|---|
/ul/li[1] | 选取属于 ul子元素的第一个 li元素。 |
/ul/li[last()] | 选取属于 ul子元素的最后一个 li元素。 |
/ul/li[last()-1] | 选取属于 ul子元素的倒数第二个 li元素。 |
//ul/li[position()❤️] | 选取最前面的两个属于 ul元素的子元素的 li元素。 |
//a[@title] | 选取所有拥有名为 title的属性的 a元素。 |
//a[@title=‘xx’] | 选取所有 a元素,且这些元素拥有值为 xx的 title属性。 |
//a[@title>10] > < >= <= != | 选取 a元素的所有 title元素,且其中的 title元素的值须大于 10。 |
/body/div[@price>35.00] | 选取body下price元素值大于35的div节点 |
实例
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
/ul/* | 选取 bookstore 元素的所有子元素。 |
//* | 选取文档中的所有元素。 |
//title[@*] | 选取所有带有属性的 title 元素。 |
//node() | 获取所有节点 |
路径表达式 | 结果 |
---|---|
//book/title | //book/price | 选取 book 元素的所有 title 和 price 元素。 |
//title | //price | 选取文档中的所有 title 和 price 元素。 |
/bookstore/book/title | //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
-
模糊查询
//div[contains(@id, "he")] # 查询所有id属性中包含he的div标签 //div[starts-with(@id, "he")] # 查询所有id属性中包以he开头的div标签 //div/h1/text() # 查找所有div标签下的直接子节点h1的内容 //div/a/@href # 获取a里面的href属性值 //* #获取所有 //*[@class="xx"] #获取所有class为xx的标签 # 获取节点内容转换成字符串 c = tree.xpath('//li/a')[0] result=etree.tostring(c, encoding='utf-8') print(result.decode('UTF-8'))
contains
contains函数是XPath中用于检查字符串是否包含另一个字符串的函数。它的语法如下:
contains(string1, string2)
string1 是要被检查的字符串。
string2 是要在 string1 中查找的字符串。
如果 string1 包含 string2,则函数返回 true,否则返回 false。
使用contains函数进行页面解析
在上面图片中可以看到通过class不好进行定位就可以使用contains对ne-if 进行相关定位
news_titles = tree.xpath('//div[contains(@ne-if, "{{")]/text()')
这样就能快速定位到我们想要的标签
案例
豆瓣Top250基于xpath解析:
import requests
from lxml import etree
url = "https://movie.douban.com/top250?start=0"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36"
}
resp = requests.get(url, headers=headers)
tree = etree.HTML(resp.text) # 加载页面源代码
items = tree.xpath('//li/div[@class="item"]/div[@class="info"]')
for item in items:
title = item.xpath('./div[@class="hd"]/a/span[1]/text()')[0]
rating_num = item.xpath('./div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')[0]
comment_num = item.xpath('./div[@class="bd"]/div[@class="star"]/span[4]/text()')[0]
print(title, rating_num, comment_num)