一个简易的python 爬虫源码分析

爬虫流程

之前没了解过相关东西,觉得大体流程无非是发送http request, 然后把爬来的数据进行存储。

读了一个相关代码实现后,往深里钻,里面东西还特别多。核心流程还是一样,但是考虑到效率就会涉及到很多东西。流程方面可以参考这里

代码仓库

网上谁便找了个,代码量不大,适合学习使用这里

代码解读

类图

在这里插入图片描述

  • 其中WebSpider 是对外的门面类,其中聚合了抓取线程、解析线程、保存结果线程;还聚合了抓取任务队列、解析任务队列、保存任务队列。
  • 其中线程有反过来关联WebSpider 一次来操作队列; 线程中有关联了具体干活的Worker类。
  • Worker泛化具体的抓取、解析、保存操作。里面自定义具体操作。抓取里面进行http请求,解析里面进行正则匹配, 保存进行输出重定向。

流程图

维护了三个任务队列:Fetch, Parser, Saver 分别代表抓取队列、解析队列、保存队列。
初始

Fetch Queue Parser Queue Saver Queue 1、http request的结果 2、解析html文档,提取需要的结果 3、抓取当前页面中的其他链接 Fetch Queue Parser Queue Saver Queue
  • 其中,1、2、3步骤都在各自的线程中运行,初始时会在Fetch Queue 中塞入一个初始url,以此保证后续动作的进行。
  • 整个流程由队列中数据驱动进行,至于线程停止的时机,直到所有任务队列为空时,因为Parser会把解析到的次级url放入Fetch队列,那么队列如何保证可以有为空的条件呢,这里Paser干活类中有个控制抓取url层级的值,当抓取的url层级超过限制的层级后,就不会再往Fetch 队列中插入了。

关键知识

布隆过滤

  • python 引入pybloom_live 包来使用。可以理解为hashmap的替代,但是在数据量巨大时hashmap 会有空间占用巨大的问题。 但是布隆过滤器也有缺点,他可以告诉“某样东西一定不存在或者可能存在”,即无法保证确定的存。
  • 此程序中在Fetch 获取到新url后会更新过滤器中值。在数据量小时,看不出布隆过滤的优势。

Queue

此程序的关键代码理解我觉得主要是queue的使用,剖开具体的操作细节,代码运行流程可以通过Queue 来看明白。
可以看下面一个生产者–消费者问题,代码中的queue 的使用是一样的。


def test_multiply_thread_queue():
    num_fetch_threads = 5
    enclosure_queue = Queue()

    def consumer(i, q):
        while True:
            print("consumer begin")
            url = q.get(block=True)
            print('%s: consumer: %s end. %s' % (i, url, time.ctime()))
            # time.sleep(1)
            q.task_done()

    for i in range(num_fetch_threads):
        worker = Thread(target=consumer, args=(i, enclosure_queue))
        worker.setDaemon(True)
        worker.start()

    def producer(i, q):
        itm = 'url {}'.format(i)
        # print('producer: %s begin. %s' % (itm, time.ctime()))
        #time.sleep(i)
        q.put(itm)
        print('producer: %s end. %s' % (itm, time.ctime()))

    num_product_threads = 5
    for i in range(num_product_threads):
        worker = Thread(target=producer, args=(i, enclosure_queue))
        worker.setDaemon(True)
        worker.start()

    # Now wait for the queue to be empty, indicating that we have
    # processed all of the downloads.
    print('*** Main thread waiting')
    enclosure_queue.join()
    print('*** Done')
  • Queue 自身保证线程安全。这里join 为’Blocks until all items in the queue have been gotten and processed.’,等待所有任务被取出, 而后往下执行。这里join的效果可以通过调整consumer和producer中的sleep看出效果。
  • 当生产者执行较快,消费者线程肯定能消费完才结束程序;
    当生产者较慢,消费者较快时,生产者可能没生产几个就会退出程序,因为在enclosure_queue.join()时发现队列为空,主线程直接往下执行了。
  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值