目录
活动地址:CSDN21天学习挑战赛
**
**
获取到html字符串,经过lxml库解析,变成HTML页面,再通过xpath的提取可以获取到需要的数据。

lxml看是xml和html的解析器,主要功能是解析xml和html中的数据;lxml是一款高性能的python html、xml解析器,也可以利用xpath语法,来定位特定的元素即节点信息。
使用命令 【pip install lxml】下载安装lxml库。

解析HTML网页用到了lxml库中的etree类。
示例1:解析HTML字符串
- from lxml import etree
-
- text = '''
-
- CSDN
- python
- lxml解析HTML
-
- '''
-
- # 初始化,传入一个html形式的字符串
- html = etree.HTML(text)
- print(html)
- print(type(html))
- # 将字符串序列化为html字符串
- result = etree.tostring(html).decode('utf-8')
- print(result)
- print(type(result))
输出结果:
- <Element html at 0x1c9ba29e880>
- <class 'lxml.etree._Element'>
- <html><body>
- <div class="key">
- <div class="Websit">CSDNdiv>
- <div class="Lang">pythondiv>
- <div class="Content">lxml解析HTMLdiv>
- div>
- body>html>
- <class 'str'>
示例2:读取并解析HTML文件
- from lxml import etree
-
- # 初始化,传入一个html形式的字符串
- html = etree.parse('test.html')
-
- # 将字符串序列化为html字符串
- result = etree.tostring(html).decode('utf-8')
- print(result)
- print(type(result))
-
- html=etree.HTML(result)
- print(html)
- print(type)
显示结果:
- <html><body>
- <div class="key">
- <div class="Website">CSDNdiv>
- <div class="Lang">pythondiv>
- <div class="Content">lxml解析HTMLdiv>
- div>
- body>html>
- <class 'str'>
- <Element html at 0x19f271bf4c0>
- <class 'type'>
总结:
如果有一个html的字符串,可以使用etree.HTML(html_str)函数初始化为html,然后使用etree.tostring(html).decode('utf-8')序列化为html字符串;
如果html内容被存储到文件中,那么可以使用etree.parse(filename)解析文件,然后使用etree.tostring(html).decode('utf-8')序列化为html字符串。
xpath是在xml文档中查找信息的语言,可用来在xml文档中对元素和属性进行遍历。
常用的路径表达式有:
| 表达式 | 说明 |
| nodename | 选取此节点的所有子节点 |
| / | 从根节点选取 |
| // | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
| . | 选取当前节点 |
| .. | 选取当前节点的父节点 |
| @ | 选取属性 |
示例:
| 表达式 | 说明 |
| bookstore | 选取bookstore元素的所有子节点 |
| /bookstore | 选取根元素bookstore。注释:假如路径起始于正斜杠/,此路径始终代表到某元素的绝对路径! |
| bookstore/book | 选取属于bookstore的子元素的所有book元素 |
| //book | 选取所有book子元素,不管它们在文档中的位置 |
| bookstore//book | 选择属于bookstore元素的后代的所有book元素,不管它们位于bookstore之下的什么位置 |
| //@lang | 选取名为lang的所有属性 |
谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中。
| 路径表达式 | 说明 |
| /bookstore/bok[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 |
xpath通配符可以用来选取未知的xml元素。
| 通配符 | 说明 |
| * | 匹配任何元素节点 |
| @* | 匹配任何属性节点 |
| node() | 匹配任何类型的节点 |
示例:
| 路径表达式 | 说明 |
| /bookstore/* | 读取bookstore元素的所有子元素 |
| //* | 选取文档中的所有元素 |
| html/node()/meta/@* | 选取html下面任意节点下的meta节点的所有属性 |
| //title[@*] | 选取所有带有属性的title元素 |
通过在路径表达式中使用|运算符,可以选取若干个路径。
示例:
| 路径表达式 | 结果 |
| //book/title | //book/price | 选取book元素的所有title和price元素 |
| //title | //price | 选取文档中的所有title和price元素 |
| /bookstore/book/title | //price | 选取属于bookstore元素的book元素的所有title元素,以及文档中所有的price元素 |
xpath使用示例:
新建test.html文件:
-
- <div>
- <ul>
- <li class="item-0"><a href="link1.html">first itema>li>
- <li class="item-1"><a href="link2.html">second itema>li>
- <li class="item-inactive"><a href="link3.html"><span class="bold">third itemspan>a>li>
- <li class="item-1"><a href="link4.html">fourth itema>li>
- <li class="item-0"><a href="link5.html">fifth itema>li>
- ul>
- div>
⚪ 获取所有的
- # 获取所有的
- 标签
- from lxml import etree
-
- html = etree.parse('test.html')
- print(type(html))
-
- result = html.xpath('//li')
-
- print(result)
- print(len(result))
- print(type(result))
- print(type(result[0]))
显示结果:
- <class 'lxml.etree._ElementTree'>
- [<Element li at 0x21eca60ad80>, <Element li at 0x21eca60ae40>, <Element li at 0x21eca60ae80>, <Element li at 0x21eca60aec0>, <Element li at 0x21eca60af00>]
- 5
- <class 'list'>
- <class 'lxml.etree._Element'>
⚪ 获取
- # 获取
- 标签的所有class属性
- from lxml import etree
-
- html = etree.parse('test.html')
-
- result = html.xpath('//li/@class')
-
- print(result)
- print(len(result))
- print(type(result))
- print(type(result[0]))
显示结果:
- ['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']
- 5
- <class 'list'>
- <class 'lxml.etree._ElementUnicodeResult'>
⚪ 获取
- # 获取
- 标签的所有class属性
- from lxml import etree
-
- html = etree.parse('test.html')
-
- result = html.xpath('//li/a[@href="link1.html"]')
-
- print(result)
- print(len(result))
- print(type(result))
- print(type(result[0]))
显示结果
- [
0x141b529f380>] - 1
- <class 'list'>
- <class 'lxml.etree._Element'>
⚪ 获取
- # 获取
- 标签的所有class属性
- from lxml import etree
-
- html = etree.parse('test.html')
-
- result = html.xpath('//li//span')
-
- print(result)
显示结果:
- [<Element span at 0x1da409cf480>]
- 1
⚪ 获取
- # 获取
- 标签的所有class属性
- from lxml import etree
-
- html = etree.parse('test.html')
-
- result = html.xpath('//li/a//@class')
-
- print(result)
- print(len(result))
显示结果:
- ['bold']
- 1
⚪ 获取最后一个
- # 获取
- 标签的所有class属性
- from lxml import etree
-
- html = etree.parse('test.html')
-
- result = html.xpath('//li[last()]/a/@href')
-
- print(result)
- print(len(result))
显示结果:
- ['link5.html']
- 1
⚪ 获取倒数第二个元素的内容
- # 获取
- 标签的所有class属性
- from lxml import etree
-
- html = etree.parse('test.html')
-
- result = html.xpath('//li[last()-1]/a')
-
- print(result)
- print(result[0].text)
- print(len(result))
显示结果:
- [<Element a at 0x19937dbf300>]
- fourth item
- 1
⚪ 获取class值为bold的标签名
- # 获取
- 标签的所有class属性
- from lxml import etree
-
- html = etree.parse('test.html')
-
- result = html.xpath('//*[@class="bold"]')
-
- print(result)
- print(result[0].tag)
- print(len(result))
显示结果:
- [<Element span at 0x1ecc377f2c0>]
- span
- 1
全文参考: