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)常用的路径表达式

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值