lxml
是一种使用Python
编写的库,可以迅速、灵活地处理XML
和HTML
,使用XPath
语法来进行文件格式解析。上一篇中我们了解了如何使用
XPath
找到有效数据具体的定位,但是没有提起如何在Python
中使用,那么本文就将Lxml
和XPath
进行两者结合,让你能精准的从复杂的Html
代码中提取到你想要的数据。
1、Lxml安装
pip install lxml
或者使用国内地址进行加速下载:
pip install lxml -i https://pypi.tuna.tsinghua.edu.cn/simple
2、介绍
可以补全 Html
代码可以准确定位数据 可以读取文件中的代码 官方地址: https://lxml.de/index.html
3、使用Lxml补全Html代码
例如:
from lxml import etree
jier = """<head>
<meta charset="UTF-8">
<title>运维家</title>
</head>
<body>
<h1>过零丁洋</h1>
<p>惶恐滩头说惶恐,零丁洋里叹零丁。</p>
<p>人生自古谁无死,留取丹心照汗青。</p>"""
suner = etree.HTML(jier)
Finally = etree.tostring(suner, encoding="utf-8", pretty_print=True, method="html").decode("utf-8") # 通过编码再解码的方式可以展示中文
# Finally = etree.tostring(suner) # 如果html中是存英文,就直接这样子就OK了
print(Finally)
输出结果如下:
<html>
<head>
<meta charset="UTF-8">
<title>运维家</title>
</head>
<body>
<h1>过零丁洋</h1>
<p>惶恐滩头说惶恐,零丁洋里叹零丁。</p>
<p>人生自古谁无死,留取丹心照汗青。</p>
</body>
</html>
可以看到它给我们自动补全了html
标签,以及我们写了一半的body
标签。
4、从文件中读取Html代码
我们新建一个ceshi.html
文件,里面内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>运维家</title>
</head>
<body>
<h1>过零丁洋</h1>
<p>惶恐滩头说惶恐,零丁洋里叹零丁。</p>
<p>人生自古谁无死,留取丹心照汗青。</p>
</body>
</html>
使用lxml
读取:
from lxml import etree
jier = etree.parse('ceshi.html')
suner = etree.tostring(jier)
print(suner)
如果使用上面的代码来读取的话会报错如下:
Traceback (most recent call last):
File "C:\Users\22768\Desktop\python\python爬虫\002-request+Lxml.py", line 129, in <module>
jier = etree.parse('ceshi.html')
File "src\lxml\etree.pyx", line 3536, in lxml.etree.parse
File "src\lxml\parser.pxi", line 1876, in lxml.etree._parseDocument
File "src\lxml\parser.pxi", line 1902, in lxml.etree._parseDocumentFromURL
File "src\lxml\parser.pxi", line 1805, in lxml.etree._parseDocFromFile
File "src\lxml\parser.pxi", line 1177, in lxml.etree._BaseParser._parseDocFromFile
File "src\lxml\parser.pxi", line 615, in lxml.etree._ParserContext._handleParseResultDoc
File "src\lxml\parser.pxi", line 725, in lxml.etree._handleParseResult
File "src\lxml\parser.pxi", line 654, in lxml.etree._raiseParseError
File "ceshi.html", line 6
lxml.etree.XMLSyntaxError: Opening and ending tag mismatch: meta line 4 and head, line 6, column 8
Process finished with exit code 1
错误提示说的是代码中,第4行有问题,经过检查之后,难不成要改成如下样子的Html
代码嘛?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>运维家</title>
</head>
<body>
<h1>过零丁洋</h1>
<p>惶恐滩头说惶恐,零丁洋里叹零丁。</p>
<p>人生自古谁无死,留取丹心照汗青。</p>
</body>
</html>
果然,当我们改成这样子就好了,在第4行后面添加一个斜杠。。。真是无语他妈妈给他开门。。。
但是呢,我们从网页爬取的Html
代码为什么要写这个反斜杠呢?本来就可以省略的嘛,难道我们爬取下来之后还要经过处理咋地,明显不现实嘛。。。然后经过我们的多次尝试之后,发现了如下的代码是可以的:
from lxml import etree
jier = etree.HTMLParser(encoding='utf-8')
jier_2 = etree.parse('ceshi.html', parser=jier)
suner = etree.tostring(jier_2, encoding="utf-8", pretty_print=True, method="html").decode("utf-8")
print(suner)
输出结果也是没问题的,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>运维家</title>
</head>
<body>
<h1>过零丁洋</h1>
<p>惶恐滩头说惶恐,零丁洋里叹零丁。</p>
<p>人生自古谁无死,留取丹心照汗青。</p>
</body>
</html>
5、在Lxml中使用XPath语法
优化下我们的ceshi.html
文件,让素材更加丰富,优化之后代码如下;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>运维家</title>
</head>
<body>
<h1>过零丁洋</h1>
<div>
<ul>
<li class="item-0"><a href="jier1.html">文天祥</a></li>
<li class="item-1"><a href="jier2.html">惶恐滩头说惶恐</a></li>
<li class="item-inactive"><a href="jier3.html"><span class="bold">零丁洋里叹零丁</span></a></li>
<li class="item-1"><a href="jier4.html">人生自古谁无死</a></li>
<li class="item-0"><a href="jier5.html">留取丹心照汗青</a></li>
</ul>
</div>
</body>
</html>
(1)获取所有li
标签
from lxml import etree
jier = etree.HTMLParser(encoding='utf-8')
jier_2 = etree.parse('ceshi.html', parser=jier)
suner = etree.tostring(jier_2, pretty_print=True, method="html").decode('utf-8')
jier = etree.HTML(suner)
Finally = jier.xpath('//li', )
for i in Finally:
for a in i:
if a.text == None:
for b in a:
print(b.text)
else:
print(a.text)
输出结果如下:
文天祥
惶恐滩头说惶恐
零丁洋里叹零丁
人生自古谁无死
留取丹心照汗青
(2)获取所有li
标签下的所有class
属性的值
from lxml import etree
jier = etree.HTMLParser(encoding='utf-8')
jier_2 = etree.parse('ceshi.html', parser=jier)
suner = etree.tostring(jier_2, pretty_print=True, method="html").decode('utf-8')
jier = etree.HTML(suner)
Finally = jier.xpath('//li/@class')
print(Finally)
输出结果为:
['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']
(3)获取最后一个li
标签中的href
值
from lxml import etree
jier = etree.HTMLParser(encoding='utf-8')
jier_2 = etree.parse('ceshi.html', parser=jier)
suner = etree.tostring(jier_2, pretty_print=True, method="html").decode('utf-8')
jier = etree.HTML(suner)
Finally = jier.xpath('//li[last()]/a/@href')
print(Finally)
输出结果为:
['jier5.html']
(4)获取倒数第二个li
标签中的内容
from lxml import etree
jier = etree.HTMLParser(encoding='utf-8')
jier_2 = etree.parse('ceshi.html', parser=jier)
suner = etree.tostring(jier_2, pretty_print=True, method="html").decode('utf-8')
jier = etree.HTML(suner)
Finally = jier.xpath('//li[last()-1]/a')
print(Finally[0].text)
输出结果为:
人生自古谁无死
至此,本文结果,更多相关内容,每次更新。

往期推荐
文章转载自运维家,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




