爬虫之 lxml模块的安装与使用示例
lxml模块是一个第三方模块,安装之后使用
1.1 lxml模块的安装对发送请求获取的xml或html形式的响应内容进行提取
pip/pip3 install lxml
1.2 爬虫对html提取的内容
- 提取标签中的文本内容
- 提取标签中的属性的值
- 比如,提取a标签中href属性的值,获取url,进而继续发起请求
-
导入lxml 的 etree 库
from lxml import etree 【此时这行代码以不能用, from lxml import html etree = html.etree, 用这两行代码代替之前的一行代码】
-
利用etree.HTML,将html字符串(bytes类型或str类型)转化为Element对象,Element对象具有xpath的方法,返回结果的列表
html = etree.HTML(text) ret_list = html.xpath("xpath语法规则字符串")
-
xpath方法返回列表的三种情况
- 返回空列表:根据xpath语法规则字符串,没有定位到任何元素
- 返回由字符串构成的列表:xpath字符串规则匹配的一定是文本内容或某属性的值
- 返回由Element对象构成的列表:xpath规则字符串匹配的是标签,列表中的Element对象可以继续进行xpath
运行下面的代码,查看打印的结果
示例代码:
from lxml import html
etree = html.etree
text = '''
-
first item
-
second item
-
third item
-
fourth item
-
a href="link5.html">fifth item # 最后一个只开了头,没有尾
'''
html = etree.HTML(text) # 此处text也可以直接写网页返回的结果response.content.decode()
# 获取href的列表和title的列表
href_list = html.xpath("//li[@class='item-1']/a/@href")
title_list = html.xpath("//li[@class='item-1']/a/text()") # 默认返回的是列表
print(href_list)
print(title_list)
#
# 组装成字典
for href in href_list:
item = {}
item['href'] = href
item['title'] = title_list[href_list.index(href)]
print(item)
运行效果:
修改示例代码:
from lxml import html
etree = html.etree
text = '''
-
first item
-
second item
-
third item
-
fourth item
-
a href="link5.html">fifth item # 最后一个只开了头,没有尾
'''
html = etree.HTML(text)
# 获取href的列表和title的列表
href_list = html.xpath("//li[@class='item-1']/a/@href")
title_list = html.xpath("//li[@class='item-1']/a/text()") # 默认返回的是列表
print(href_list)
print(title_list)
for href, title in zip(href_list, title_list): # 以相同索引分别遍历2个列表
print(href, title)
运行效果:
优化示例代码:
from lxml import html
etree = html.etree
text = '''
-
first item
-
second item
-
third item
-
fourth item
-
a href="link5.html">fifth item # 最后一个只开了头,没有尾
'''
html = etree.HTML(text)
# 获取href的列表和title的列表
href_list = html.xpath("//li[@class='item-1']/a/@href")
title_list = html.xpath("//li[@class='item-1']/a/text()") # 默认返回的是列表
print(href_list)
print(title_list)
# 根据li标签进行分组
li_list = html.xpath("//li[@class='item-1']")
# 在每一组中继续进行数据的提取
for li in li_list:
item = {}
item['href'] = li.xpath("./a/@href")[0] if len(li.xpath("./a/@href")) > 0 else None
item['title'] = li.xpath("./a/text()")[0] if len(li.xpath("./a/text()")) > 0 else None
print(item)
运行效果:
-
注意:将每个class为item-1的li标签作为1条新闻数据。提取a标签的文本内容以及链接,组装成一个字典。
-
先分组,再提取数据,可以避免数据的错乱
-
对于空值要进行判断
-