本阶段本文主要学习响应之后如何从响应中提取我们想要的数据,在本阶段本文中我们会讲解一些常用的方法和模块,基本上我们以后遇到的情况在掌握本阶段本文之后都能搞定
对html或xml形式的文本提取特定的内容,就需要我们掌握lxml模块的使用和xpath语法。
要想利用lxml模块提取数据,需要我们掌握xpath语法规则。接下来我们就来了解一下xpath helper插件,它可以帮助我们练习xpath语法
在谷歌浏览器中对当前页面测试xpath语法规则
我们以windos为例进行xpath helper的安装
* 可以在chrome应用商城进行下载,如果无法下载,也可以从下面的链接进行下载
?
* 下载地址:<https://pan.baidu.com/s/1UM94dcwgus4SgECuoJ-Jcg> 密码:337b
学习xpath语法需要先了解xpath中的节点关系
每个html、xml的标签我们都称之为节点,其中最顶层的节点称为根节点。我们以xml为例,html也是一样的
author
是title
的第一个兄弟节点
表达式 | 描述 |
---|---|
nodename | 选中该元素。 |
/ | 从根节点选取、或者是元素和元素间的过渡。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
text() | 选取文本。 |
接下来我们通过itcast的页面来练习上述语法:http://www.itcast.cn/
//h2/text()
//a/@href
/html/head/title/text()
/html/head/link/@href
可以根据标签的属性值、下标等来特定的节点
路径表达式 | 结果 |
---|---|
//title[@lang="eng"] | 选择lang属性值为eng的所有title元素 |
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()>1] | 选择bookstore下面的book元素,从第二个开始选择 |
//book/title[text()='Harry Potter'] | 选择所有book下的title元素,仅仅选择文本为Harry |
Potter的title元素 | |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title |
元素,且其中的 price 元素的值须大于 35.00。 |
从itcast的页面中,选择所有学科的名称、第一个学科的链接、最后一个学科的链接:http://www.itcast.cn/
//div[@class="nav_txt"]//a[@class="a_gd"]
//div[@class="nav_txt"]/ul/li[1]/a/@href
//div[@class="nav_txt"]/ul/li[last()]/a/@href
可以通过 通 配符来选取未知的html、xml的元素
通配符 | 描述 |
---|
从itcast的页面中 http://www.itcast.cn/ ,选中全部的标签、全部的属性
//*
//node()
lxml模块是一个第三方模块,安装之后使用
对发送请求的xml或html形式的响应内容进行提取
pip/pip3 install lxml
from lxml import etree
ret_list = html.xpath("xpath语法规则字符串")
* 返回空列表:根据xpath语法规则字符串,没有定位到任何元素
* 返回由字符串构成的列表:xpath字符串规则匹配的一定是文本内容或某属性的值
* 返回由Element对象构成的列表:xpath规则字符串匹配的是标签,列表中的Element对象可以继续进行xpath
运行下面的代码,查看打印的结果
from lxml import etree
text = '''
<div>
<ul>
<li class="item-1">
<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>
</ul>
</div>
'''
?
html = etree.HTML(text)
#href的列表和title的列表
href_list = html.xpath("//li[@class='item-1']/a/@href")
title_list = html.xpath("//li[@class='item-1']/a/text()")
#组装成字典
for href in href_list:
item = {}
item["href"] = href
item["title"] = title_list[href_list.index(href)]
print(item)
将下面的html文档字符串中,将每个class为item-1的li标签作为1条新闻数据。提取a标签的文本内容以及链接,组装成一个字典。
text = ''' <div> <ul>
<li class="item-1"><a>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>
</ul> </div> '''
''' ?
#根据li标签进行分组
html = etree.HTML(text)
li_list = html.xpath("//li[@class='item-1']")
#在每一组中继续进行数据的提取
for li in li_list:
item = {}
item["href"] = li.xpath("./a/@href")[0] if len(li.xpath("./a/@href"))>0 else None
item["title"] = li.xpath("./a/text()")[0] if len(li.xpath("./a/text()"))>0 else None
print(item)
运行下边的代码,观察对比html的原字符串和打印输出的结果
from lxml import etree
html_str = ''' <div> <ul>
<li class="item-1"><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>
</ul> </div> '''
?
html = etree.HTML(html_str)
?
handeled_html_str = etree.tostring(html).decode()
print(handeled_html_str)
打印结果和原来相比:
li
标签html
等标签<html><body><div> <ul> <li class="item-1">first item</li> <li class="item-1">second item</li> <li class="item-inactive">third item</li> <li class="item-1">fourth item</li> <li class="item-0">fifth item </li></ul> </div> </body></html>
结 论:
lxml.etree.tostring
函数可以将转换为Element对象再转换回html字符串lxml.etree.tostring
的返回结果作为提取数据的依据原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。