# 准备一个html格式文档
doc = '''
<div>
<ul>
<li class="item-0"><a href="https://ask.hellobi.com/link1.html">first item</a></li>
<li class="item-1"><a href="https://ask.hellobi.com/link2.html">second item</a></li>
<li class="item-inactive"><a href="https://ask.hellobi.com/link3.html">third item</a></li>
<li class="item-1"><a href="https://ask.hellobi.com/link4.html">fourth item</a></li>
<li class="item-0"><a href="https://ask.hellobi.com/link5.html">fifth item</a>
</ul>
</div>
'''
# 导入模块
from lxml import etree
# etree.html是将爬取的网页数据再生成标准网页格式数据,因为有些网页不规范写的时候。
# etree.html可以解析html文件:(服务器上返回的html数据)。
# 解析HTML,返回根节点对象
# 将字符串格式的文件转化为html文档
tree = etree.HTML(doc)
# print(tree) #==> <Element html at 0x26f62635140> 表明这是一个html文档
# 调用 tostring() 方法即可输出修正后的 HTML 代码,但是结果是 bytes 类型
result = etree.tostring(tree)
# 利用 decode() 方法转成 str 类型
# print(result.decode('utf-8'))
# 在这里我们首先导入了 LXML 库的 etree 模块,然后声明了一段 HTML 文本,
# 调用 HTML 类进行初始化,这样我们就成功构造了一个 XPath 解析对象,
# 在这里注意到 HTML 文本中的最后一个 li 节点是没有闭合的,
# 但是 etree 模块可以对 HTML 文本进行自动修正。
# 在这里我们调用 tostring() 方法即可输出修正后的 HTML 代码,但是结果是 bytes 类型,
# 在这里我们利用 decode() 方法转成 str 类型,结果如下:
'''
<html><body><div>
<ul>
<li class="item-0"><a href="https://ask.hellobi.com/link1.html">first item</a></li>
<li class="item-1"><a href="https://ask.hellobi.com/link2.html">second item</a></li>
<li class="item-inactive"><a href="https://ask.hellobi.com/link3.html">third item</a></li>
<li class="item-1"><a href="https://ask.hellobi.com/link4.html">fourth item</a></li>
<li class="item-0"><a href="https://ask.hellobi.com/link5.html">fifth item</a>
</li></ul>
</div>
</body></html>
'''
# etree.parse是对标准网页格式数据进行解析用的。
# etree.parse直接接受一个文档,按照文档结构解析(本地文件)。
# etree.HTMLParser()指定解析器HTMLParser会根据文件修复HTML文件中缺失的如声明信息)
# b.html的内容就是doc
tree = etree.parse('./b.html', etree.HTMLParser())
result = etree.tostring(tree)
# print(result.decode('utf-8'))
# 这次的输出结果略有不同,多了一个 DOCTYPE 的声明,不过对解析无任何影响,结果如下:
'''
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><div>
<ul>
<li class="item-0"><a href="https://ask.hellobi.com/link1.html">first item</a></li>
<li class="item-1"><a href="https://ask.hellobi.com/link2.html">second item</a></li>
<li class="item-inactive"><a href="https://ask.hellobi.com/link3.html">third item</a></li>
<li class="item-1"><a href="https://ask.hellobi.com/link4.html">fourth item</a></li>
<li class="item-0"><a href="https://ask.hellobi.com/link5.html">fifth item</a>
</li></ul>
</div></body></html>
'''
# 定位
tree = etree.parse('./b.html', etree.HTMLParser())
# result = tree.xpath('/html') # [<Element html at 0x1f20a07aac0>]
# result = tree.xpath('/html//li') # 跟下面返回一致
# result = tree.xpath('/html//li[@class]')
# result = tree.xpath('/html//li[2]') # 选哪个li [<Element li at 0x13fcd6daec0>]
# result = tree.xpath('/html//li/a/text()') # 返回列表,['first item', 'second item', 'third item', 'fourth item', 'fifth item']
# result = tree.xpath('/html//li[@class="item-0"]') # 指定元素 [<Element li at 0x18664a7acc0>, <Element li at 0x18664a7ad80>]
# print(result)
li_list = tree.xpath('/html//li')
for li in li_list:
# 从每一个li中提取到文字信息
# ./当前节点下面
result = li.xpath('./a/text()')
print(result) # 返回列表
# 拿到属性值:@属性
result2 = li.xpath('./a/@href')
print(result2) # 返回列表
标签:xpath,etree,python,tree,爬虫,li,item,html,result
From: https://www.cnblogs.com/Wesuiliye/p/17173685.html