XPath语法参考:https://blog.csdn.net/houyanhua1/article/details/86484770
demo.py(lxml模块,XPath语法提取页面数据):
# coding=utf-8
from lxml import etree
# 模拟html页面
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>标签缺少对应的结束标签,lxml可以自动进行修正。
html = etree.HTML(text) # 返回Element对象。 参数text可以是字符串也可以是bytes类型
print(html) # <Element html at 0x7f9e1f0b9948> Element对象
# 查看Element对象中包含的字符串
# print(etree.tostring(html).decode()) # 会自动修正html代码 (添加html和body标签,将li标签闭合等)
# lxml会自动修正html代码,但修正后的代码可能会改变原有的html结构。
# 获取class为item-1 的所有li下的a的href属性
ret1 = html.xpath("//li[@class='item-1']/a/@href") # 参数就是XPath语法的字符串
print(ret1) # ['link2.html', 'link4.html']
# 获取class为item-1 li下的a的文本
ret2 = html.xpath("//li[@class='item-1']/a/text()")
print(ret2) # ['first item', 'second item', 'fourth item']
# 每个li是一条新闻,把url和文本组成字典
for href in ret1:
my_dict = {}
my_dict["href"] = href
my_dict["title"] = ret2[ret1.index(href)]
print(my_dict) # {'href': 'link2.html', 'title': 'first item'}
# 如果某个a标签没有href属性,那么后边的my_dict中的href和title会对应错误。
print("*"*100)
# (分组)根据li标签进行分组,对每一组继续写xpath
ret3 = html.xpath("//li[@class='item-1']") # 返回Element对象的列表
print(ret3) # [<Element li at 0x7f9e1f0b9a08>, <Element li at 0x7f9e1f0b9b08>, <Element li at 0x7f9e1f0b9b48>]
for i in ret3:
my_dict= {}
my_dict["title"] = i.xpath("a/text()")[0] if len(i.xpath("./a/text()"))>0 else None
my_dict["href"] = i.xpath("./a/@href")[0] if len( i.xpath("./a/@href"))>0 else None
print(my_dict) # {'href': None, 'title': 'first item'}
# 指定默认值None,那么href和title不会对应错误。(通过分组来提取数据,不容易出现对应错乱)