目录
1.lxml常用操作
紧记,lxml返回结果是一个列表。
(1)常用的路径表达式
nodename 选取nodename节点的所有子节点
/ 从根节点选取,路径起始于/
// 选取所有的节点,不考虑他们的位置
. 选取当前节点
.. 选取当前节点的父节点
div/a 选取div下所有a标签子节点
div//a 选取div下所有a标签节点,不管a是子元素还是孙元素
./a 选取当前节点下所有a标签子节点
.//a 选取当前节点下所有a标签节点,不管a是子元素还是孙元素
//a 选取所有a子元素,而不管它们在文档中的位置。
../a 选取父元素下的a节点
div.xpath[//@class] //选取名为 class 的所有属性。
div.xpath[(@class)] //含class属性的div节点
div.xpath[not(@class)] //不含class属性的div节点
div.xpath[a/@href] //选取a标签的href属性
div.xpath[a/text()] //选取a标签下的文本
div.xpath('string(.)') //提取出div节点下除去标签的所有文本
div.xpath('string(..)') //提取出div父节点下除去标签的所有文本
div/Node[last()] //取出div路径下最后一个Node节点
div[contains(text(),a)] //文本包含字符串a的div节点
div[count(span)=2] //包含两个span节点的div节点
谓语查找特定节点
/artical/div[1] 选取所有属于artical 子元素的第一个div元素
/artical/div[last()] 选取所有属于artical子元素的最后一个div元素
/artical/div[last()-1] 选取所有属于artical子元素的倒数第2个div元素
/artical/div[position()<3] 选取所有属于artical子元素的前2个div元素
//div[@class] 选取所有拥有属性为class的div节点
//div[@class=”main”] 选取所有div下class属性为main的div节点
//div[price>3.5] 选取所有div下元素值price大于3.5的节点 a=response.xpath('//a[contains(text(),"闻")]')
a=response.xpath('//a[contains(text(),"闻")]/text()') //提取text
a=response.xpath('//a[contains(text(),"闻")]/@href') //获取href
a=response.xpath('//a[contains(text(),"闻")]/@name') //获取name
Xpath通配符
//* 选取所有元素,匹配任何元素节点
//div/* 选取所有属于div元素的所有子节点
//div[@*] 选取所有带属性的元素,@* 匹配任何属性节点
/bookstore/* 选取 bookstore 元素的所有子元素。
//* 选取文档中的所有元素。
//title[@*] 选取所有带有属性的 title 元素。
选取多个路径
//div | //table 选取文档中所有的div和table节点
//div/a | //div/p 选取所有div元素的a和p 元素
artical/div/pl | //span 选取所有div下的pl和文档中所有span
(2)选取父子兄弟节点
轴名称 | 表达式 | 描述 |
ancestor | ./ancestor::* | 选取当前节点的所有先辈节点(父、祖父) |
ancestor-or-self | ./ancestor-or-self::* | 选取当前节点的所有先辈节点以及节点本身 |
descendant | ./descendant::* | 返回当前节点的所有后代节点(子节点、孙节点) |
child | ./child::* | 返回当前节点的所有子节点 |
parent | ./parent::* | 选取当前节点的父节点 |
following | ./following::* | 选取文档中当前节点结束标签后的所有节点 |
following-sibling | ./following-sibling::* | 选取当前节点之后的兄弟节点 |
preceding | ./preceding::* | 选取文档中当前节点开始标签前的所有节点 |
preceding-sibling | ./preceding-sibling::* | 选取当前节点之前的兄弟节点 |
self | ./self::* | 选取当前节点 |
attribute | ./attribute::* | 选取当前节点的所有属性 |
child::book 选取所有属于当前节点的子元素的 book 节点。
attribute::lang 选取当前节点的 lang 属性。
child::* 选取当前节点的所有子元素。
attribute::* 选取当前节点的所有属性。
child::text() 选取当前节点的所有文本子节点。
child::node() 选取当前节点的所有子节点。
descendant::book 选取当前节点的所有 book 后代。
ancestor::book 选择当前节点的所有 book 先辈。
ancestor-or-self::book 选取当前节点的所有 book 先辈以及当前节点(如果此节点是 book 节点)
child::*/child::price 选取当前节点的所有 price 孙节点。
result=html.xpath('//li[1]/ancestor::*') #获取所有祖先节点
result1=html.xpath('//li[1]/ancestor::div') #获取div祖先节点
result2=html.xpath('//li[1]/attribute::*') #获取所有属性值
result3=html.xpath('//li[1]/child::*') #获取所有直接子节点
result4=html.xpath('//li[1]/descendant::a') #获取所有子孙节点的a节点
result5=html.xpath('//li[1]/following::*') #获取当前子节之后的所有节点
result6=html.xpath('//li[1]/following-sibling::*') #获取当前节点的所有同级节点
result=html.xpath('//li[contains(@class,"aaa")]/a/text()') #获取所有li节点下a节点的内容
result1=html.xpath('//li[1][contains(@class,"aaa")]/a/text()') #获取第一个li
result2=html.xpath('//li[last()][contains(@class,"aaa")]/a/text()') #获取最后一个li
result3=html.xpath('//li[position()>2 and position()<4][contains(@class,"aaa")]/a/text()') #获取第三个li
result4=html.xpath('//li[last()-2][contains(@class,"aaa")]/a/text()') #获取倒数第三个li
(3)功能函数进行模糊搜索
函数 | 用法 | 解释 |
starts-with | //div[starts-with(@id,”ma”)] | 选取id值以ma开头的div节点 |
contains | //div[contains(@id,”ma”)] | 选取所有id值包含ma的div节点 |
and | //div[contains(@id,”ma”) and contains(@id,”in”)] | 选取id值包含ma和in的div节点 |
text() | //div[contains(text(),”ma”)] | 选取节点文本包含ma的div节点 |
a=response.xpath('//a[starts-with(@title,"注册时间")]') a=response.xpath('//a[contains(text(),"闻")]')
(4)使用正则表达式定位节点
利用href配合正则表达式定位
response.xpath('//a[re:test(@href,"^\/index\.php\?m=News&a=details&id=1&NewsId=\d{1,4}")]')
利用text结合正则表达式定位
a=response.xpath('//a[re:test(text(),"\w{4}")]')
//对href中的部分字符串进行选择
response.xpath('//a[@name="_l_p_n"]/@href').re('\/s.*?list\.htm')
(5)XPath表达式中的运算符
运算符 | 描述 | 实例 | 返回值 |
or | 或 | age=19 or age=20 | True / False |
and | 与 | age>19 and age<21 | True / False |
mod | 取余 | 5 mod 2 | 1 |
| | 取两个节点的集合 | //book | //cd | 返回所有拥有book和cd元素的节点集合 |
+ | 加 | 6+4 | 10 |
- | 减 | 6-4 | 2 |
* | 乘 | 6*4 | 24 |
div | 除法 | 8 div 4 | 2 |
= | 等于 | age=19 | true |
!= | 不等于 | age!=19 | true |
< | 小于 | age<19 | true |
<= | 小于或等于 | age<=19 | true |
> | 大于 | age>19 | true |
>= | 大于或等于 | age>=19 | true |
2.lxml 3种常见解析案例
(1)lxml解析本地文件
from lxml import etree
def gen_html(file):
f1=open(file,'r',encoding='utf-8',errors='ignore')
body=f1.read()
html=etree.HTML(body,etree.HTMLParser()) #解析HTML文本内容
return html
html=gen_html(file)
#读取本地文件
file='1.html'
f1=open(file,'r',encoding='utf-8',errors='ignore')
body=f1.read()
html=etree.HTML(body,etree.HTMLParser()) #解析HTML文本内容
(2)lxml与selenium结合案例
browser.get('https://www.amazon.com/dp/B00JDQJ6ZM')
body = browser.page_source
html = etree.HTML(body, etree.HTMLParser())
(3)lxml与request结合案例
url='https://www.baidu.com/'
response=requests.get(url)
body=response.text
html=etree.HTML(body,etree.HTMLParser())
(4)多属性匹配
若要根据多个属性确定一个节点,这时就需要同时匹配多个属性,此时可运用and运算符来连接使用:
from lxml import etree
html = etree.HTML(text1,etree.HTMLParser())
result = html.xpath('//li[@class="aaa" and @name="fore"]/a/text()')
result = html.xpath('//li[contains(@class,"bbb") and @name="fore"]/a/text()')
(5)列出html所有节点
from lxml import etree
etree.tostring(html,pretty_print=True)
etree.tostring(a,pretty_print=True)
a=html.xpath('/html/*')[0]
a.tag