1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 【Python爬虫学习笔记4】结合Xpath与lxml库解析数据

【Python爬虫学习笔记4】结合Xpath与lxml库解析数据

时间:2022-08-05 16:54:26

相关推荐

【Python爬虫学习笔记4】结合Xpath与lxml库解析数据

在之前的学习中了解了如何使用爬虫向目标服务器发送请求并获取响应,而此后便是要对响应进行处理,这里的处理在爬虫中通常指的是数据解析,即将相应内容数据化以方便我们进行有效数据的提取。在此过程中,有许多解析数据的方法,本节介绍利用Xpath和lxml库来解析数据。

Xpath

Xpath(全称XML Path Language,XML路径语言),是一门在XML和HTML文档中查找信息的语言,它提供了非常简明的路径选择表达式,可用来对网页的元素及属性进行遍历查找。

语法规则:

1.选取节点

XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。

2.谓语

谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中。

3.通配符

通配符,顾名思义指匹配所有节点,在爬虫中通配符用的不多,主要有如下两种:

4.选择多个路径

在Xpath路径选择表达式中可以通过在表达式中使用“|”运算符选取若干个路径。如表达式”//div | //div/p”表示选取所有div节点及其下的p节点。

5.运算符

在Xpath表达式中可以包含运算符,其中共有14种运算符,包括’|’ , ’+’ , ’-‘ , ’*’ , ’div’ , ’=’, ’!=’ , ’<‘ , ’<=’ , ’>’ , ’>=’, ’or’ , ’and‘ , ’mod’,这些表达式含义比较明了,其通常运用于谓语中,如” //div[@class='text' and @id='description']”表示选取class属性为’text’且id为’description’的div节点。

lxml库

lxml 是一个HTML/XML解析器,主要功能是解析和提取 HTML/XML 数据。lxml和正则一样由C实现,是一款高性能的 Python HTML/XML 解析器,利用它和XPath语法可以快速定位特定元素及节点以捕获信息。在此介绍如何利用lxml获取HTML文档对象。

安装方法

使用pip进行安装:pip install lxml

基本使用

##示例1——使用lxml.etree模块获取HTML对象from lxml import etree# 网页源代码text = """<div><ul><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>"""# 使用etree.HTML()方法获取_Element对象,传入参数为待解析的源代码htmlElement = etree.HTML(text)# 返回htmlElement的类型print(type(htmlElement))# 返回htmlElement的内容print(etree.tostring(htmlElement, encoding='utf-8').decode('utf-8'))

由上述结果可知,etree.HTML()返回的是一个<class 'lxml.etree._Element'>的对象,因此在获取源代码内容时还需要使用tostring的方法将其进行字符编码转化,且在转化后我们可以留意到其会自动地将源代码结构补充完整。

除了直接对HTML字符串进行解析外,我们也可以对html文件进行解析。

##示例2——使用lxml.etree对html文件进行解析from lxml import etree# xml方式解析def parse_file_xml():htmlElement = etree.parse("myfile.html")print(etree.tostring(htmlElement, encoding='utf-8').decode('utf-8'))# html方式解析def parse_file_html():parser = etree.HTMLParser(encoding='utf-8')htmlElement = etree.parse('myfile.html',parser=parser)print(etree.tostring(htmlElement, encoding='utf-8').decode('utf-8'))if __name__ =='__main__':print('\nxml文件解析')parse_file_xml()print('\nhtml文件解析')parse_file_html()

在示例2中,我们使用了两种解析html文件的方法,这主要是为了应对一些不规范HTML网页(比如有的Tag标签未匹配dui应)而采取的措施,etree解析器默认为XML方式解析,然而当解析一个不规范页面时就会产生错误,因此有时候就有必要设置特定的解析器(parser)来解析页面。

Xpath与lxml结合使用数据解析示例

在解析数据过程中,lxml用于产生源代码的_Element对象,而Xpath则是作用于_Element对象之上进行节点的检索,故解析基本思路为先通过lxml获取对象,然后利用Xpath对其进行节点检索。下面先通过几个小例子说明二者的基本使用,然后再以一个较为综合的示例来说明具体的解析流程。

<!源代码><table class="tablelist" cellpadding="0" cellspacing="0"><tr class="even"><td class="l square"><a target="_blank" href="position_detail.php?id=44256&keywords=&tid=0&lid=2218">25664-技术运营工程师(深圳)</a></td><td>技术类</td><td>2</td><td>深圳</td><td>-09-16</td></tr><tr class="odd"><td class="l square"><a target="_blank" href="position_detail.php?id=44252&keywords=&tid=0&lid=2218">15570-3D场景设计师(深圳)</a></td><td>设计类</td><td>1</td><td>深圳</td><td>-09-16</td></tr><tr class="even"><td class="l square"><a target="_blank" href="position_detail.php?id=44253&keywords=&tid=0&lid=2218">18425-国际支付产品软件测试工程师</a><spanclass="hot">&nbsp;</span></td><td>技术类</td><td>2</td><td>深圳</td><td>-09-16</td></tr></table>

##示例3——使用html.xpath选取节点(其返回的是一个列表)from lxml import etree# 设置解析器并获取_Element对象parser = etree.HTMLParser(encoding='utf-8')html = etree.parse('example.html',parser=parser)# 获取所有tr标签trs = html.xpath('//tr') #[<Element tr at 0x2132da8c6c8>, <Element tr at 0x2132da8c708>, <Element tr at 0x2132da8c748>]# 获取第2个tr标签tr2 = html.xpath('//tr[2]')[0] #<Element tr at 0x2132da8c708># 获取所有class等于even的tr标签tags= html.xpath('//tr[@class="even"]') #[<Element tr at 0x20cd0b736c8>, <Element tr at 0x20cd0b73748>]# 获取所有a标签的href属性hrefs = html.xpath('//a/@href') #或hrefs = [element.get('href') for element in html.xpath('//a')]

‘’’

Output:

['position_detail.php?id=44256&keywords=&tid=0&lid=2218', 'position_detail.php?id=44252&keywords=&tid=0&lid=2218', 'position_detail.php?id=44253&keywords=&tid=0&lid=2218']

’’’

在上述简单介绍后便可以开始一个相对完整的网页数据解析,还是以上述源代码为例,具体如下:

##示例4——综合演练,获取网页上所有职位信息from lxml import etree# 获取_Element对象parser = etree.HTMLParser(encoding='utf-8')html = etree.parse('tencent.html',parser=parser)# 获取所有tr节点,并设置存放数据的容器positiontrs = html.xpath('//tr')positions = []# 依次遍历节点并存储数据for tr in trs:href = tr.xpath('.//a/@href')[0] title = tr.xpath('.//td[1]//text()')[0]category = tr.xpath('./td[2]//text()')[0]nums = tr.xpath('./td[3]//text()')[0]address = tr.xpath('./td[4]//text()')[0]pub_time = tr.xpath('./td[5]//text()')[0]data = {'url':href,'title':title,'category':category,'nums':nums,'address':address,'pub_time':pub_time}positions.append(data)for position in positions:print(position)

这里要注意的是,在解析数据时我们所写的表达式中前面都有一个’.’表示选取当前节点之下的指定路径的节点,如果缺少则指定为根节点下或全局节点,由此会出现错误。由于Xpath返回的是一个列表,所以获取具体对象时需要添加[0]操作;另外,对于节点的文本字符串,可以利用函数text()来获取。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。