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 方法就行