Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
在上篇文章中我们提到了去重操作,并使用了Python中的集合set进行了url的去重。然而,Redis中也存在的这种名为“集合”的数据类型,同样可以用来进行去重操作。
引入依赖库
import requests
import redis
import fake_useragent
from lxml import etree
本文使用的解析库依然是lxml。当然,使用re或者bs4也是可以的。
请求连接
首先需要连接redis,注意:一定要开启redis。
redis-server
定义1个全局变量cli用于实例化Redis对象。
# 连接redis
cli = redis.Redis()
然后进行循环请求。
# 初始页码
i = 0
while True:
response = requests.get(
url=url.format(i),
headers=headers,
proxies=proxies,
)
# 页码+1
i += 1
# 将html转化为可用xpath解析的对象
tree = etree.HTML(response.text)
# 解析页面
link_and_title = get_data(tree)
# 展示数据
show_data(link_and_title)
# 如果redis中的数据大于1000则跳出循环
if cli.scard('jianshu:start_urls') > 1000:
break
print('完成任务!')
解析页面
使用xpath语句提取页面信息。
def get_data(tree):
"""
解析页面
:param tree: xpath对象
:return: title link
"""
title = tree.xpath('//div[@id="list-container"]/ul/li/div[@class="content"]/a[@class="title"]/text()')
link = tree.xpath('//div[@id="list-container"]/ul/li/div[@class="content"]/a[@class="title"]/@href')
# 将链接与标题合并为1个字典
link_and_title = dict(zip(link, title))
return link_and_title
展示数据
def show_data(link_and_title):
"""
通过redis展示数据
:param link_and_title: 文章链接与标题
:return: None
"""
for k in link_and_title.keys():
# 向redis集合中添加链接
judge = cli.sadd('jianshu:start_urls', k)
# 获取集合中的数据数量
num = cli.scard('jianshu:start_urls')
if num > 1000:
break
if judge:
link = 'https://www.jianshu.com' + k
print(num, link, link_and_title[k])
虽然该函数为show_data(展示数据),但其核心是对redis的操作,包括sadd向集合插入数据、scard获取集合中的数据数量。
结语
上述show_data函数中,我们向redis集合中添加了url链接,所以说,当使用多台pc端连接redis进行爬取时,便达到了分布式的效果。
分布式爬虫说白了就是把爬虫的关键功能以分布式形式部署到多台机器上然后一起爬它,所以说我们一般要配合一些异步操作以最大化爬虫效率,其中,多线程和协程是爬虫中的常用异步技术,接下来我们将开启多线程技术应用到爬虫中。
本章的完整代码请参考下面链接。
https://github.com/macxin123/spider/blob/master/jianshu/redis_jianshu.py