Python爬虫如何入门?

作者: xiyouMc | 来源:发表于2017-05-08 16:05 被阅读81次

    源自公众号:DeveloperPython

    其实,“入门”最好的方式是以项目开始,这样实践起来你会被目标驱动。从而,不用一步一步慢慢的学习模块化的东西。

    其实,知识体系里面的每一个知识点类似于图里的点。边就是知识体系的依赖关系,那么整个图也就是一个有向无环图。因为学习A的经验可以帮助到你学习B。因此,入门的东西根本不用学习,因为入门点根本不存在。

    同时,你需要学习的是如何去做一个大的项目,来亲身体会爬虫, 并一步步学习爬虫的知识点。

    那么,我总结下知乎上的相关知识点:

    1. 爬虫的工作原理
    2. 基本的Https爬虫工具:Scrapy
    3. 分布式爬虫系统。也就是维护一个集群机器来高效的完成分布式队列。Github上也有一个现成的例子: nvie/rq
    4. rq和Scrapy的结合: rolando/scrapy-redis
    5. 后续处理: 网页处理grangier/python-goose 存储(Mongodb)

    以下,我将基于xiyouMc/WebHubBot的经验来讲:

    1. 爬虫的怎么工作的

      爬虫的另一个意思其实就是(Spider) ,互联“网”也是它的环境。简单的来说,也就是你需要用这个蜘蛛来把相关的网站的所有角落(网页)都爬一边。

      那么,你可以选择一个自己感兴趣的平台,如知乎、淘宝等等的。

      我这里通过PornHub来讲解。比如,我们访问PornHub的首页,里面会出现很多链接。同时最初我们的目标是拿到所有的视频标题、视频简介、视频链接或者其他有用信息。然后我们兴高采烈的将整个首页都爬下来,这里想象下,你就是将整个页面完完整整的Copy了下来。

      然后,我们随便点击一个链接进入视频详情页,进入第二个页面之后,那就会看到具体的视频标题、简介等等的。那么这只是一个视频,我们又是如何做到爬取整站的数据呢。这里可以动下脑子,一种是返回再回到首页去拿一个链接,另一种则是基于第一步爬下来的首页来找下一个链接。这里,当然是第二种方案。同时我们要做去重,爬过的链接,就不要再去爬第二遍。

      所以,理论上如果后续的所有视频详情页都是从首页可达的话,那么我们就一定可以将所有网页都爬下来。

      以下是Python的伪代码实现:

      
      from Queue import Queue
      home_page = 'https://www.pornhub.com/'
      link_queue = Queue()
      seen = set()
      seen.insert(home_page)
      link_queue.put(home_page)
      
      while(True):
          if link_queue.size() > 0:
              current_url = url_queue.get() #拿到队列中第一个url
              links = save(current_url)  #保存这个页面的html,并返回当前页面的所有link
              for link in links:
                  if link not in seen:
                      seen.put(link)
                      link_queue.put(link)
          else:
              break
      

      以上就是一个简单的伪代码来爬取pornhub中视频资源的例子。当然, 这只是一个非常简单的例子,其实爬虫是一个非常复杂的项目,类似的就是搜索引擎需要爬取整站的数据,更是需要一整个团队来开发和维护。

    2. 效率

      如果,使用上述的代码来爬取PornHub的话,那么你是绝对无法在一天时间内完成500万的海量数据的,更别说在短时间内爬取PornHub的所有数据。

      那么,问题出在哪?爬的网页太多太多了,而且上面的代码太慢太慢了。

      PornHub的全网有N个页面,那么分析下判重的时间复杂度将是 N * log(N),因为每个网页都要遍历一遍,而使用Set来做判重,需要 log(N) 的复杂度。

      所以,我们需要一个成熟的判重方案。Bloom Filter。 它是一个空间效率很高的随机数据结构。官方简介

      Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。Bloom Filter的这种高效是有一定代价的:在判断一个元素是否属于某个集合时,有可能会把不属于这个集合的元素误认为属于这个集合(false positive)。因此,Bloom Filter不适合那些“零错误”的应用场合。而在能容忍低错误率的应用场合下,Bloom Filter通过极少的错误换取了存储空间的极大节省。

      有兴趣可以详细学习下这个算法。

      简单的来说,它是一种利用Hash的方法来判重的。并且在使用固定的内存,不随url的数量增加而增长,以 O(1)的效率判断url是否已经在set中。但是荣然有极小的可能性会误判,所以对于“零错误”的系统不适用。但是对于爬虫,小概率的重复爬取也是可以接受的。

      那么,以上就是判重的最快方式了。

      当然,另一个瓶颈又会出现,如果你只有一台机器,那么不管你的带宽有多大你的机器下载网页的速度还是会有瓶颈。那么,只有加快这个速度,我们使用多台机器来跑。

    3. 集群化爬取

      集群化爬取,其实不难理解。也就是将你的爬虫任务分发到n台机器来处理,当然每台机器处理的任务不同,且不重复。

      那么,假设你有100台机器,怎么用Python实现一个分布式的爬取算法呢?

      Server -> Client 。这种C/S 的模式,我相信大家也不陌生。那么分布式的系统,其实就是一台Server -> n个Client 来处理。这里我们将Server定义为 Master机,多个Client定义为多个 Slave。所以基于开始的伪代码,我们可以将link_queue 放到Master上,其他的Slave都可以通过网络跟Master联通,每当一个Slave下载完成一个页面之后,就会将这个页面的结果告知Master,同时获取一个新的link 来爬取。同时 BloomFliter 也是放在Master的,用来针对Links进行去重。 其中Slave和Server联通的方式,就是通过Redis,这是一个可以远程操作的缓存数据,提供了完善的队列管理。其次,Redis的队列中已经包含的去重的,当Push一个url 到Redis之后,某一个Slave Pop拿到数据之后,这个Url将只会在这个Slave进行处理。

      因此,我们可以用Python来实现。Slave的机器上安装Scrapy,Master上安装Redis和rq用作分布式队列。

      伪代码:

      """
      Slave
      """
      
      url = link_from_master() # 从Master机Get到最新的链接
      content = save(url) # 请求并保存这个链接下的视频信息
      send_to_master(url) # 将当前处理过的url Post给主机。
      
      """
      Master
      """
      queue = Queue()
      bf = BloomFilter()
      
      home_pages = "https://www.pornhub.com/"
      
      while(True):
          if request == 'GET':
              if distributed_queue.size()>0:
                  send(queue.get()) # 将当前url push到Redis,从而让Slave获取到。
              else:
                  break
          elif request == 'POST':
              bf.put(request.url) #将处理过的Url 保存到bf队列
      
      

      轮子: rolando/scrapy-redis

    4. 后处理

    上面的路子,其实是很简单很简单的一部分。同样的,后续你还要进行其他的处理,比如:

    • 有效的存储
    • 有效的判重
    • 有效的信息提取
    • 及时更新

    所以,不要在意如何“入门”,只管上路就好了。


    长摁‘识别二维码’,一起进步

    生活不止眼前的苟且,还有手下的代码、

    和嘴上的扯淡
    ——
    个人博客: http://xiyoumc.0x2048.com/

    Github:https://www.github.com/xiyouMc


    点击 Join,加入Python技术成长圈子,我在这里等着你。

    相关文章

      网友评论

        本文标题:Python爬虫如何入门?

        本文链接:https://www.haomeiwen.com/subject/xbamtxtx.html