URL 管理器

基本介绍

URL 管理器_第1张图片

对外接口

对外提供两个接口:一个可以提取URL,一个可以增加URL,分别对应图上的1和2。

当要爬取某个网页时,则可以从1接口提取出该网页的URL进行爬取。

有时候爬取的网页内容中会包含别的网页链接,即包含有URL,此时可以把包含的URL提取出来,放入URL管理器,以便后续进行爬取,则可以利用2接口向URL管理器新增URL

实现逻辑

图中的3:从URL管理器取出一个URL时,将该URL的状态进行更改,如已爬取、爬取成功、爬取失败等(有多少种状态根据具体需求定义),以防止重复对同一URL进行爬取。

图中的4:把从爬取的网页内容中解析出来的URL放入到URL管理器中前,需要判断URL管理器中是否已存在该URL,已存在就不需要再添加,还是防止对同一URL进行重复爬取。

数据存储

实现URL管理器有5、6、7三种,

图中的5:利用python内存实现。

用python中的set集合实现URL管理器,set集合可以实现自动去重,而且可以快速的判断集合中是否已存在某个元素。

已爬取的URL可以用一个set来表示,未爬取的URL用另一个set集合表示。从未爬取的URL集合中取出一个URL进行爬取,并将该URL标记为已爬取URL,放入到已爬取URL的set集合中。当要新增一个URL时,即把新增URL放入未爬取URL集合中,如果未爬取URL集合已存在该URL,则不会重复添加,实现了图中4的逻辑。

如果一个URL有多种状态,如正在爬取中,爬取失败、爬取成功等,可以为每种状态设置一个set集合进行存储。当状态发生转变时,从相应的集合中取出放入到转变后的集合中。

图中的6:利用Redis实现

实现逻辑和python内存类似,区别在于Python内存一旦断电就要从头开始执行,但是Redis可以保存中间状态,断电后数据不会消失

图中的7:利用MySQL数据库表

可以利用一张urls表进行存储,该表中有两个字段:url 和 url 对应的状态(已爬取、未爬取等)

URL 管理器的代码实现(python内存实现)

class UrlManage:
    """URL 管理器"""
    def __init__(self):
        # 待爬取 URL 集合
        self.new_urls = set()
        # 已爬取 URL 集合
        self.old_urls = set()

    def get_url(self):
        """从URL管理器中获取URL进行爬取"""
        if self.has_new_url():
            url = self.new_urls.pop()
            self.old_urls.add(url)
            return url
        return None

    def add_new_url(self, url):
        """新增一个 URL"""
        if url is None or len(url) == 0:
            return
        if url in self.old_urls or url in self.new_urls:
            return
        self.new_urls.add(url)

    def add_new_urls(self, *urls):
        """批量新增 URL"""
        if urls is None or len(urls) == 0:
            return
        for url in urls:
            self.add_new_url(url)

    def has_new_url(self):
        """判断是否还有待爬取 URL"""
        return len(self.new_urls) > 0

# 测试代码
if __name__ == '__main__':
    url_manage = UrlManage()
    url_manage.add_new_url('url1')
    url_manage.add_new_urls('url1', 'url2', 'url3')
    print('已爬取set:', url_manage.old_urls, '未爬取set:', url_manage.new_urls)
    print('-' * 20)

    url = url_manage.get_url()
    print(url)
    print('已爬取set:', url_manage.old_urls, '未爬取set:', url_manage.new_urls)
    print('-' * 20)

    url = url_manage.get_url()
    print(url)
    print('已爬取set:', url_manage.old_urls, '未爬取set:', url_manage.new_urls)
    print('-' * 20)

    url = url_manage.get_url()
    print(url)
    print('已爬取set:', url_manage.old_urls, '未爬取set:', url_manage.new_urls)
    print('-' * 20)

    print(url_manage.has_new_url())
    print('已爬取set:', url_manage.old_urls, '未爬取set:', url_manage.new_urls)

你可能感兴趣的:(python,爬虫,爬虫,python)