赞
踩
nodename : 选取此节点的所有子节点
/ : 从当前节点选取直接子节点
// : 从当前节点选取子孙节点
. : 选取当前节点
.. : 选取当前节点的父节点
@ : 选取属性
3. 使用
3.1安装lxml库
3.2 基本用法:
from lxml import etree #从lxml 导入etree模块 text = '''html 文档 ''' #声明 HTML文本 html = etree.HTML(text) #调用HTML类, 进行初始化, 构造了一个XPath解析队形, 可以自动修正HTML文本 result = etree.tostring(html) # 调用tostring() 方法即可输出修正后的HTML代码, 结果是bytes类型的, print(result.decode('utf-8')) #利用decode() 方法将其转化成str类型
还可以直接读取文本文件进行解析
html = etree.parse('猫眼.html',etree.HTMLParser()) ret = etree.tostring(html) print(ret.decode('utf-8'))
3.3 找到所有节点
我们一般都会用 // 开头的XPath来选取所有符合要求的节点
from lxml import etree html = etree.parse('猫眼.html', etree.HTMLParser()) ret = html.xpath('//*') #我们使用*代表匹配所有 for i in ret: print(i) #获取的是一个列表,包含了所有的节点 # #每个节点都是一个 Element 类型, 后面跟着节点名称
当然我们也可以指定节点名称,要选取所有的li节点, 可以使用// 直接加上节点名称即可, 调用时直接使用xpath()方法即可
from lxml import etree html = etree.parse('猫眼.html', etree.HTMLParser()) ret = html.xpath('//li') #指定li节点 for i in ret: print(i)
3.4 子节点
我们通过/ 或者 // 即可查找元素的子节点或者子孙节点
选择所有的li节点的所有直接 a 子节点 :
ret = html.xpath('//li/a')
选择ul节点下的所有a子孙节点 ret = html.xpath('//ul//a)
ret = html.xpath('//ul/a) 匹配结果为空, 因为ul直接子节点没有a
3.5 父节点
父节点用.. 来实现
查找href属性为 link4.html 的a节点,然后再获取其父节点, 然后再获取其class属性
ret = html.xpath('//a[@href="/board/7"]/../@class') print(ret[0]) #我们还可以通过parent::* 来获取父标签 ret = html.xpath('//a[@href="/board/7"]/parent::*/@class')
3.6 属性匹配
选取class为item-0的li节点
ret = html.xpath('//li[@class="item-0"]')
3.7 文本获取
利用xpath中的text()方法可以获取节点中的文本,
如果想要获取紫苏节点内部的所有文本, 可以直接使用// 加 text() 方法,这样可以保证获取到最全面的文本信息, 但是可能会夹杂一些换行符等特殊字符,
如果想要获取某些特定子孙节点下的所有文本, 可以先选取到特定的子孙节点,然后再调用text() 方法获取其内部文本.
3.8 属性获取
ret = html.xpath('//a[@href="/board/7"]/@href')
注意: 中括号加属性名和值来限定某个属性是 属性匹配
@加属性名是获取该属性的值
3.9 属性多值匹配
当标签属性值拥有多个值的时候,属性匹配就不好用了,要用contains函数
ret = html.xpath('//a[contains(@href,"/board/7")]')
contains 函数第一个传入属性名, 第二个传入属性的值, 只要元素的href属性包含这个值,就会被匹配到
3.10 多属性匹配
利用多个属性确定一个节点,需要匹配多个属性,利用and符连接起来.
ret = html.xpath('//a[contains(@href,"lalala") and @id="1"]')
3.10 按序选择
result = html.xpath('//li[1]/a/text()')#查找所有li标签中的第一个, 注意索引从1开始
result = html.xpath(//li[last()]/a/text())#查找最后一个li标签
result = html.xpath(//li[position()<3]/a/text())#选取位置序号为1和2的元素
result = html.xpath(//li[last()-2])/a/text()#选取倒数第三个
这里我们使用了position(), last() 函数, 详见w3school
3.11 节点选择轴
result = html.xpath('//li[1]/ancestor::*)
#ancestor轴,可以获取所有祖先节点,其后需要跟两个::, 然后是节点选择器,我们
直接使用*, 表示获取所有祖先节点 html , body , div , ul
result= html.xpath('//li[1]/ancestor::div')
获取祖先节点中的div标签
result= html.xpath('//li[1]/attribute::*')
attribute轴可以获得所有属性值, 其后跟的选择器还是*, 代表获取所有属性的值
result= html.xpath('//li[1]/child::[@href="link1-html"])
#child轴可以获取所有直接子节点, 我们又给他加了限定条件,选取href属性为xx的元素
result= html.xpath('//li[1]/descendant::span')#descendant轴可以获取所有子孙节点, 获取所有子孙节点中的span标签
result= html.xpath('//li[1]/following::*[2]')#following 可以获取当前节点之后的所有节点, 获取当前节点后续的第二个节点
result= html.xpath('//li[1]/following-sibling::*')#获取所有同级的后续节点
查询更多python lxml用法, 可以查看 http://lxml.de/
1 from lxml importetree2
3 url = 'https://maoyan.com/board/4'
4
5 defget_html(url,data):6
7 ret = requests.get(url, params=data) #获取网页源代码
8
9 return etree.HTML(ret.text) #用HTML类处理
10
11
12 defgetmovieinfo(html):13 for i in range(1,11):14
15 num = html.xpath(f'//dd[{i}]/i/text()') #获取所有的dd标签, 其中每一个dd标签就是一个电影的信息
16
17 name = html.xpath(f'//dd[{i}]/div/div/div[1]/p[1]/a/text()')18
19
20 star = html.xpath(f'//dd[{i}]/div/div/div[1]/p[2]/text()')21
22 releasetime = html.xpath(f'//dd[{i}]/div/div/div[1]/p[3]/text()')23
24 movie_info = f'{num[0]} {name[0]} {star[0].strip()} {releasetime[0]}'
25 print(movie_info)26
27
28 for i in range(10):29 data ={30 'offset': i * 10
31 }32 html = get_html(url, data=data)33 getmovieinfo(html)
补充: 今天遇到个网站,我想抓取他的a标签,但是他有一些a标签的href是js代码,我不想要这些a标签,可以用a[stats-with(@href, 'h')]来实现
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。