python - crawler 之 lxml parse & lxml解析html
目录1.lxml常用操作(1)常用的路径表达式(2)选取父子兄弟节点(3)功能函数进行模糊搜索(4)使用正则表达式定位节点(5)XPath表达式中的运算符2.lxml 3种常见解析案例(1)lxml解析本地文件(2)lxml与selenium结合案例(3)lxml与request结合案例(4)多属性匹配(5)列出html所有节点1.lxml常用操作紧记,lxml返回结果是一个列表。(1)常用的路径
目录
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

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)