页面分析:
每个字段都很规整页面所有数据都存放在div标签下,且class属性值为cellm;每个div标签下都存放一对数据。
解析思路:
- 将本地html文件读取并转化成HTML对象可以使用xpath语法进行解析
- xpath语法解析出每一个div标签,报存在divs中
- 遍历每一个div在div标签中再次使用xpath语法解析出键值对,并保存在字典中
from lxml import etree
# 解析本地html,返回字典数据类型
def parse_html(file_path):
with open(file_path, 'r') as f:
html = etree.HTML(f.read())
divs = html.xpath("//div[contains(@class, 'cellm')]")
res = {}
for div in divs:
key = div.xpath("./span[1]/text()")[0].replace('/', '_')
value = div.xpath("./span[2]/text()")[0]
res[key] = value
return res
问题1:如何将本地的html文件转化成HTML对象,进而可以使用xpath语法解析
这里需要使用lxml库中的etree。
上面这种方式测试是可以的,打开文件读取f.read(), 成一个字符文本,进而使用etree.HTML()转化为HTML对象。可以使用下面的方法打印查看HTML对象的内容
print(etree.tostring(html, encoding='utf-8').decode('utf-8'))
etree转化html成文本型,存在先编码成二进制,再解码成文本这一过程,打印结果不会造成乱码
问题2:如何实现div对象下使用xpath继续解析
这里遇到一个问题,开始也是想不明白:已经解析到每一个div标签了再使用xpath解析时该div标签不应该时跟节点了吗?那么下面这种方式为什么仍然选出很多内容呢?
# 注意xpath里二个斜线
key = div.xpath("//span[1]/text()")
这种方式选出的span值时所有的,xpath仍然是从根节点开始查找,所以这里需要修改为相对位置
# 注意xpath是./ 表示相对位置
key = div.xpath("./span[1]/text()")
还有注意的一点是,xpath解析出的结果是放在列表中返回,因此需要使用索引进行取值赋值给key和value。
问题3:解析时使用模糊匹配的方式
html.xpath("//div[contains(@class, 'cellm')]")
这是考虑到有些div标签class值时不一样的,但是都包含cellm这个值。
问题4:取标签中的值和标签属性的值
姓名,年龄等一些字段并不是标签的一个属性,需要取值如何实现?
/text() 方法可以去值
/@herf 获取某一属性的值