02-大规模异步新闻爬虫:实现功能强大、简洁易用的网址池

你好,我是悦创。

对于比较大型的爬虫来说,URL 管理的管理是个核心问题,管理不好,就可能重复下载,也可能遗漏下载。这里,我们设计一个 URL Pool 来管理 URL 。
这个 URL Pool 就是一个 生产者-消费者模式

在这里插入图片描述
依葫芦画瓢,URLPool 就是这样的:
在这里插入图片描述

我们从网址池的使用目的出发来设计网址池的接口,它应该具有以下功能:

  • 往池子里面添加 URL;
  • 从池子里面取 URL 以下载;
  • 池子内部要管理 URL 状态;

前面我提到 URL 的状态有以下 4 中:

  • 已经下载成功
  • 下载多次失败无需再下载
  • 正在下载
  • 下载失败要再次尝试

前两个是永久状态,也就是已经下载成功的不再下载,多次尝试后仍失败的也就不再下载,它们需要永久存储起来,以便爬虫重启后,这种永久状态记录不会消失,已经成功下载的 URL 不再被重复下载。永久存储的方法有很多种:

  • 比如,直接写入文本文件,但它不利于查找某个 URL 是否已经存在文本中;
  • 比如,直接写入 MySQL 等关系型数据库,它利用查找,但是速度又比较慢;
  • 比如,使用 key-value 数据库,查找和速度都符合要求,是不错的选择!

我们这个 URL Pool 选用 redis 来作为 URL 状态的永久存储。

UrlDB 的实现

# -*- coding: utf-8 -*-
# @Time    : 2021/5/17 2:41 下午
# @Author  : AI悦创
# @FileName: UrlDB.py
# @Software: PyCharm
# @Blog    :http://www.aiyc.top
# @公众号   :AI悦创
from redis import Redis


class UrlDB(object):
    '''
    Use redis to store URLs what have been done(succeed or faile)
    '''
    status_failure = b'0'
    status_success = b'1'

    def __init__(self, db_name):
        self.name = db_name
        self.db = Redis(host='localhost', port=6379, db=self.name)

    def set_success(self, url):
        """
        请求成功的 url
        """
        if isinstance(url, str):
            url = url.encode('utf8')
        try:
            self.db.set(url, self.status_success)
            s = True
        except:
            s = False
        return s

    def set_failure(self, url):
        """
        请求失败的 url
        """
        if isinstance(url, str):
            url = url.encode('utf8')
        try:
            self.db.set(url, self.status_failure)
            s = True
        except:
            s = False
        return s

    def has(self, url):
        """
        判断我们的 url 是否存在
        """
        if isinstance(url, str):
            url = url.encode('utf8')
        try:
            # attr = self.db.get(url)
            attr = self.db.exists(url)
            return attr
        except:
            pass
        return False

UrlDB 将被 UrlPool 使用,主要有三个方法被使用:

  • has(url) 查看是否已经存在某 url
  • set_success(url) 存储 url 状态为成功
  • set_failure(url) 存储 url 状态为失败

UrlPool 的实现

而正在下载和下载失败次数这两个 URL 的状态只需暂时保存在内容即可,我们把它们放到 UrlPool 这个类中进行管理。接着我们来实现网址池:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI悦创|编程1v1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值