目录
4.4 获取“li标签”下的hre为link1.html的“a标签”
4.6 获取“li标签”下的“a标签”里的所有class属性
4.7 获取最后一个“li标签”的“a标签”中的href属性
⭐不是因为看清了去学习,正是因为看不清所以才不断学习......🌈
活动地址:CSDN21天学习挑战赛
1. 爬虫提取网页数据流程图
2. lxml库
lxml是XML和HTML的解析器,其主要功能是解析和提取XML和HTML中的数据,是一款高性能的Python HTML、XML解析器,也可以利用Xpath语法,来定位特定的元素及节点信息。lxml库是Python第三方库,需要自己安装。
2.1 解析HTML网页
解析HTML网页主要使用的是lxml库中的etree类。
应用举例1:解析HTML字符串
from lxml import etree
text = '''
<html><body>
<div class="key">
<div class="name">小浪</div>
<div class="age">23</div>
<div class="address">山东</div>
</div>
</body></html>
'''
#开始初始化
html = etree.HTML(text) #这需要传入一个html形式的字符串
print(html) #输出:<Element html at 0x1f77f541600>
print(type(html)) #输出:<class 'lxml.etree._Element'>
#将字符串序列化为html字符串
result = etree.tostring(html).decode('utf-8')
print(result)
# 输出:
# <html><body>
# <div class="key">
# <div class="name">小浪</div>
# <div class="age">23</div>
# <div class="address">山东</div>
# </div>
# </body></html>
print(type(result)) #输出:<class 'str'>
应用举例2:读取并解析HTML文件,首先创建一个html文件。
from lxml import etree
#读取html文件
html = etree.parse('test.html')
#将html内容格式化
result = etree.tostring(html).decode('utf-8')
print(result)
# 输出:
# <html><body>
# <div class="key">
# <div class="name">小浪</div>
# <div class="age">23</div>
# <div class="address">山东</div>
# </div>
# </body></html>
print(type(result)) #输出:<class 'str'>
html = etree.HTML(result)
print(html) #输出:<Element html at 0x2d30ea69180>
print(type(html)) #输出:<class 'lxml.etree._Element'>
3. Xpath
Xpath(XML Path Language)是一们在XML文档中查找信息的语言,可以用来在XML文档中对元素和属性进行遍历。
3.1 选取节点
表达式 | 说明 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
用法举例:
表达式 | 说明 |
---|---|
bookstore | 选取bookstore元素的所有节点 |
/bookstore | 选取根元素bookstore。注释:假如路径起始于正斜杠(/),则此路径始终代表到某元素的绝对路径 |
bookstore/book | 选取属于bookstore的子元素的所有book元素 |
//book | 选取所有book子元素,而不管它们在文档中的位置 |
bookstore//book | 选择属于bookstore元素的后代的所有book元素,而不管它们位于bookstore之下的什么位置 |
//@lang | 选取名为lang的所有属性 |
3.2 谓语
谓语用来查找某个特定的节点或者包括某个特定的值得节点,被嵌在方括号([ ])中。
路径表达式 | 说明 |
---|---|
/bookstore/book[1] | 选取属于bookstore子元素的第一个book元素 |
/bookstore/book[last()] | 选取属于bookstore子元素的最后一个book元素 |
/bookstore/book[last()-1] | 选取属于bookstore子元素的倒数第二个book元素 |
/bookstore/book[position()<3] | 选取最前面的两个属于bookstore子元素的book元素 |
//title[@lang] | 选取所有拥有名为lang属性的title元素 |
//title[@lang='eng'] | 选取所有title元素,且这些元素拥有eng的lang属性 |
/bookstore/book[price>35.00] | 选取bookstore元素的所有book元素,且其中的price元素的值须大于35.00 |
/bookstore/book[price>35.00]/title | 选取bookstore元素中的book元素的所有title元素,且其中的price元素的值须大于35.00 |
3.3 选取未知节点
Xpath通配符可用来选取未知的XML元素。
通配符 | 说明 |
---|---|
* | 匹配任何元素节点 |
@* | 匹配任何属性节点 |
node() | 匹配任何类型的节点 |
用法举例:
路径表达式 | 说明 |
---|---|
/bookstore/* | 选取bookstore元素的所有子元素 |
//* | 选取文档中的所有元素 |
html/node()/meta/@* | 选择html下面任意节点下的meta节点的所有属性 |
//title[@*] | 选取所有带有属性的title元素 |
3.4 选取若干元素
通过路径表达式中使用“|”运算符,可以选取若干个路径。
用法举例:
路径表达式 | 结果 |
---|---|
//book/title | //book/price | 选取book元素的所有title和price元素 |
//title | //price | 选取文档中的所有title和price元素 |
//bookstore/book/title | //price | 选取属于bookstore元素的所有titile元素,以及文档中所有的price元素 |
4. Xpath实战
Chrome浏览器自带 Xpath Hepler可以很方便的获取标签路径。
4.1 创建测试文件
新建一个test.html文件,且包括以下内容:
<!-- test.html -->
<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"><span class="bold">third item</span></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>
4.2 获取所有的"li标签"
from lxml import etree
html = etree.parse('test.html')
#输出etree.parse()返回的数据类型
print(type(html)) #输出:<class 'lxml.etree._ElementTree'>
result = html.xpath('//li')
#打印<li>标签的元素集合
print(result) #输出:[<Element li at 0x29ca2316c40>, <Element li at 0x29c93295a80>, <Element li at 0x29c932958c0>, <Element li at 0x29c932957c0>, <Element li at 0x29c9314fd80>]
print(len(result)) #输出:5
print(type(result)) #输出:<class 'list'>
print(type(result[0])) #输出:<class 'lxml.etree._Element'>
4.3 获取“li标签”的所有class属性
from lxml import etree
html = etree.parse('test.html')
result = html.xpath('//li/@class')
print(result)#输出:['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']
4.4 获取“li标签”下的hre为link1.html的“a标签”
from lxml import etree
html = etree.parse('test.html')
result = html.xpath('//li/a[@href="link1.html"]')
print(result)#输出:[<Element a at 0x26b4825df00>]
4.5 获取“li标签”下的所有“span标签”
from lxml import etree
html = etree.parse('test.html')
# result = html.xpath('//li/span')
# 注意:这么写是不对的
# 因为/用来获取子元素,而<span>不是<li>的子元素,所以用双斜杠
result = html.xpath('//li//span')
print(result)#输出:[<Element span at 0x1f71a379280>]
4.6 获取“li标签”下的“a标签”里的所有class属性
from lxml import etree
html = etree.parse('test.html')
result = html.xpath('//li/a//@class')
print(result)#输出:['bold']
4.7 获取最后一个“li标签”的“a标签”中的href属性
from lxml import etree
html = etree.parse('test.html')
result = html.xpath('//li[last()]/a/@href')
print(result)#输出:['link5.html']
4.8 获取倒数第二个元素的内容
from lxml import etree
html = etree.parse('test.html')
result = html.xpath('//li[last()-1]/a')
print(result[0].text)#输出:fourth item
4.9 获取class值为bold的标签名
from lxml import etree
html = etree.parse('test.html')
result = html.xpath('//*[@class="bold"]')
#tag方法可以获取标签名
print(result[0].tag)#输出:span