• URL 管理器


    基本介绍

    对外接口

    对外提供两个接口:一个可以提取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内存实现)

    1. class UrlManage:
    2. """URL 管理器"""
    3. def __init__(self):
    4. # 待爬取 URL 集合
    5. self.new_urls = set()
    6. # 已爬取 URL 集合
    7. self.old_urls = set()
    8. def get_url(self):
    9. """从URL管理器中获取URL进行爬取"""
    10. if self.has_new_url():
    11. url = self.new_urls.pop()
    12. self.old_urls.add(url)
    13. return url
    14. return None
    15. def add_new_url(self, url):
    16. """新增一个 URL"""
    17. if url is None or len(url) == 0:
    18. return
    19. if url in self.old_urls or url in self.new_urls:
    20. return
    21. self.new_urls.add(url)
    22. def add_new_urls(self, *urls):
    23. """批量新增 URL"""
    24. if urls is None or len(urls) == 0:
    25. return
    26. for url in urls:
    27. self.add_new_url(url)
    28. def has_new_url(self):
    29. """判断是否还有待爬取 URL"""
    30. return len(self.new_urls) > 0
    31. # 测试代码
    32. if __name__ == '__main__':
    33. url_manage = UrlManage()
    34. url_manage.add_new_url('url1')
    35. url_manage.add_new_urls('url1', 'url2', 'url3')
    36. print('已爬取set:', url_manage.old_urls, '未爬取set:', url_manage.new_urls)
    37. print('-' * 20)
    38. url = url_manage.get_url()
    39. print(url)
    40. print('已爬取set:', url_manage.old_urls, '未爬取set:', url_manage.new_urls)
    41. print('-' * 20)
    42. url = url_manage.get_url()
    43. print(url)
    44. print('已爬取set:', url_manage.old_urls, '未爬取set:', url_manage.new_urls)
    45. print('-' * 20)
    46. url = url_manage.get_url()
    47. print(url)
    48. print('已爬取set:', url_manage.old_urls, '未爬取set:', url_manage.new_urls)
    49. print('-' * 20)
    50. print(url_manage.has_new_url())
    51. print('已爬取set:', url_manage.old_urls, '未爬取set:', url_manage.new_urls)

  • 相关阅读:
    Memento(备忘录模式)
    【算法基础】时间复杂度和空间复杂度
    基于单片机PID电机控制系统设计
    ssm南工二手书交易平台毕业设计源码172334
    在 Gorm 中学习分页和排序
    基于openwrt交叉编译opencv4.9.0版本
    一线大厂软件测试面试题及答案解析,2022最强版...
    【Python】论文中常用的Matplotlib画图(三)
    如何爬取 python 进行多线程跑数据的内容
    铝合金脚手架脚手架使用前要了解的事项
  • 原文地址:https://blog.csdn.net/2301_77659011/article/details/132995523