Other
增量爬虫
增量无非就是判断,建议拿主键直接判断,下面有两个简单的例子
增量一定要判断何时不翻页(继续),不然白白浪费时间,不能依仗去重
数据库判断
即通过自己保存的数据,进行判断列表页,已出现的 url 则为已抓取,那么后续则不需要抓取
【案例】
is_repeat = False # 重复标志
for i in response.xpath('//ul[@class="list_con"]//li'):
notice_url = response.urljoin(i.xpath('./a/@href').extract_first())
# 判断是否重复
if conn_company_notice.find_one({'notice_url': notice_url}):
is_repeat = True
break
yield palp.RequestGet(url=notice_url, callback=self.parse_content)
# 翻页
if not is_repeat and page_now < page_total:
pass
redis 判断(不推荐)
Palp 默认的分布式去重有:
- redis set 去重
- redis bloom 去重(默认)
对应的过滤器如下:
- RedisSetFilter:对应 redis set 去重
- RedisBloomFilter:对应 redis bloom 去重
使用时需开启以下设置,作用是开启去重并持久化
FILTER_REQUEST = True
PERSISTENCE_REQUEST_FILTER = True
【案例】以 redis bloom 去重 为例
from palp.filter import RequestRedisBloomFilter
is_repeat = False # 重复标志
for i in response.xpath('//ul[@class="list_con"]//li'):
notice_url = response.urljoin(i.xpath('./a/@href').extract_first())
req = palp.RequestGet(url=notice_url, callback=self.parse_content)
# 判断是否重复
if RequestRedisBloomFilter().is_repeat(req):
break
yield req
# 翻页
if not is_repeat and page_now < page_total:
pass
快速二次请求
基于上一次请求的基础上进行二次请求
有两种方法:
- 原地修改
- request 的 to_dict() 方法获取字典后修改
原地修改
def parse(self, request, response) -> None:
request.xxx = xxx # 修改
yield request
to_dict()
request_dict = request.to_dict()
request_dict[xxx] = xxx # 修改
yield palp.Request(**request_dict)
个性化爬虫
比如批次爬虫,根据 redis 获取任务,其实很简单的(仅内置 mysql 批次爬取爬虫)
关于表
可以设置多种状态:已抓取,待抓取,队列中,等等
大概流程如下:
- 不论你什么需求,只要在 start_requests 函数中,设置获取方法
- 随后设置为队列中(爬取中)状态
- 在 pipeline 中(获取到结果时)设置修改已爬取状态
关于 redis
可以设置最简单的 list、或者不重复的 set 或者优先级的 zset
只要在 start_requests 函数中 直接执行对应的 pop 方法就行