原文  http://www.xgezhang.com/python_scrapy_redis_crawler.html

爬虫技术,无论是在学术领域,还是在工程领域,都扮演者非常重要的角色。相比于其他技术,爬虫技术虽然在实现上比较简单,没有那么多深奥的技术难点,但想要构建一套稳定、高效、自动化的爬虫框架,也并不是一件容易的事情。这里笔者打算就个人经验,介绍一种分布式爬虫框架的实现方法和工作原理,来给刚刚入门爬虫的同学们一点启发和提示。同时也希望大牛们能发表一些看法。

注:本文是对框架的宏观介绍,没有涉及具体代码,适合接触过爬虫和scrapy的读者。如果您对爬虫完全不了解,或者是刚刚入门,可以先看一些简单的爬虫教程和示例,这里贴几个链接:

人人网爬虫(针对老版本,目前可能没法用,但里面的技术是通用的):http://www.xgezhang.com/python_renren_spider_1.html

京东登陆爬虫: http://www.xgezhang.com/python_crawler_jingdong.html

scrapy中文教程: http://scrapy-chs.readthedocs.org/zh_CN/latest/intro/tutorial.html

爬虫,网页Xpath辅助分析工具: http://www.xgezhang.com/xpath_helper.html

框架的几个关键技术点:

scrapy : 实现爬虫的主体。scrapy是目前非常热门的一种爬虫框架,它把整个爬虫过程分为了多个独立的模块,并提供了多个基类可以供我们去自由扩展,让爬虫编写变得简单而有逻辑性。并且scrapy自带的多线程、异常处理、以及强大的自定义Settings也让整个数据抓取过程变得高效而稳定。

scrapy-redis:一个三方的基于redis的分布式爬虫框架,配合scrapy使用,让爬虫具有了分布式爬取的功能。g ithub地址: https://github.com/darkrho/scrapy-redis ,

mongodb 、mysql 或其他数据库:针对不同类型数据可以根据具体需求来选择不同的数据库存储。结构化数据可以使用mysql节省空间,非结构化、文本等数据可以采用mongodb等非关系型数据提高访问速度。具体选择可以自行百度谷歌,有很多关于sql和nosql的对比文章。

其他:一台高性能的服务器。

分布式原理:

scrapy-redis实现分布式,其实从原理上来说很简单,这里为描述方便,我们把自己的核心服务器称为master,而把用于跑爬虫程序的机器称为slave。

我们知 道,采用scrapy框架抓取网页,我们需要首先给定它一些start_urls,爬虫首先访问start_urls里面的url,再根据我们的具体逻辑,对里面的元素、或者是其他的二级、三级页面进行抓取。而要实现分布式,我们只需要在这个starts_urls里面做文章就行了。

我们在master上搭建一个redis数据库(注意这个数据库只用作url的存储,不关心爬取的具体数据,不要和后面的mongodb或者mysql混淆),并对每一个需要爬取的网站类型,都开辟一个单独的列表字段。通过设置slave上scrapy-redis获取url的地址为master地址。这样的结果就是,尽管有多个slave,然而大家获取url的地方只有一个,那就是服务器master上的redis数据库。

并且,由于scrapy-redis自身的队列机制,slave获取的链接不会相互冲突。这样各个slave在完成抓取任务之后,再把获取的结果汇总到服务器上(这时的数据存储不再在是redis,而是mongodb或者 mysql等存放具体内容的数据库了)

这种方法的还有好处就是程序移植性强,只要处理好路径问题,把slave上的程序移植到另一台机器上运行,基本上就是复制粘贴的事情。

url的生成:

看到这里,有同学应该已经想到了,上文只介绍了slave如何去读取url,那么这些url是怎么出现的呢?

首先明确一点,url是在master而不是slave上生成的。

对于每一个门类的urls(每一个门类对应redis下的一个字段,表示一个url的列表),我们可以单独写一个生成url的脚本。这个脚本要做的事很简单,就是按照我们需要的格式,构造除url并添加到redis里面。

对于slave,我们知道,scrapy可以通过Settings来让爬取结束之后不自动关闭,而是不断的去询问队列里有没有新的url,如果有新的url,那么继续获取url并进行爬取。利用这一特性,我们就可以采用控制url的生成的方法,来控制slave爬虫程序的爬取。

定时抓取:

有了上面的介绍,定时抓取的实现就变得简单了,我们只需要定时的去执行url生成的脚本即可。这里推荐linux下的crontab指令,能够非常方便的制定定时任务,具体的介绍大家可以自行查看文档。

程序化管理、web管理:

上述方法虽然能够实现一套完整的流程,但在具体操作过程中还是比较麻烦,可能的话还可以架构web服务器,通过web端来实现url的添加、爬虫状态的监控等,能够减轻非常大的工作量。这些内容如果要展开实在太多,这里就只提一下。

总结:

其实对于已有的scrapy程序,对其扩展成分布式程序还是比较容易的。总的来说就是以下几步:

  • 找一台高性能服务器,用于redis队列的维护以及数据的存储。
  • 扩展scrapy程序,让其通过服务器的redis来获取start_urls,并改写pipeline里数据存储部分,把存储地址改为服务器地址。
  • 在服务器上写一些生成url的脚本,并定期执行。

介绍完整个流程,再来介绍一些常见的防抓取屏蔽的方法:

  • 设置download_delay,这个方法基本上属于万能的,理论上只要你的delay足够长,网站服务器都没办法判断你是正常浏览还是爬虫。但它带来的副作用也是显然的:大量降低爬取效率。因此这个我们可能需要进行多次测试来得到一个合适的值。有时候download_delay可以设为一个范围随机值。
  • 随机生成User-agent:更改User-agent能够防止一些403或者400的错误,基本上属于每个爬虫都会写的。这里我们可以重写scrapy 里的middleware,让程序每次请求都随机获取一个User-agent,增大隐蔽性。具体实现可以参考http://www.sharejs.com/codes/python/8310
  • 设置代理IP池:网上有很多免费或收费的代理池,可以借由他们作为中介来爬。一个问题是速度不能保证,第二个问题是,这些代理很多可能本来就没办法用。因此如果要用这个方法,比较靠谱的做法是先用程序筛选一些好用的代理,再在这些代理里面去随机、或者顺序访问。
  • 设置好header里面的domian和host,有些网站,比如雪球网会根据这两项来判断请求来源,因此也是要注意的地方。

暂时想到这么多,以后有新的发现再补充,也欢迎各位来讨论。

转载请注明出处。

基于Python,scrapy,redis的分布式爬虫实现框架的更多相关文章

  1. Scrapy+redis实现分布式爬虫

    概述 什么是分布式爬虫 需要搭建一个由n台电脑组成的机群,然后在每一台电脑中执行同一组程序,让其对同一网络资源进行联合且分布的数据爬取. 原生Scrapy无法实现分布式的原因 原生Scrapy中调度器 ...

  2. Python 基于python操纵redis入门介绍

    基于python操纵redis入门介绍 by:授客  QQ:1033553122 测试环境 redis-3.0.7 CentOS 6.5-x86_64 python 3.3.2 基于Python操作R ...

  3. 接口自动化 [授客]基于python+Testlink+Jenkins实现的接口自动化测试框架V3.0

    基于python+Testlink+Jenkins实现的接口自动化测试框架V3.0   by:授客 QQ:1033553122     博客:http://blog.sina.com.cn/ishou ...

  4. 接口自动化 基于python+Testlink+Jenkins实现的接口自动化测试框架[V2.0改进版]

    基于python+Testlink+Jenkins实现的接口自动化测试框架[V2.0改进版]   by:授客 QQ:1033553122 由于篇幅问题,,暂且采用网盘分享的形式: 下载地址: [授客] ...

  5. 基于python+Testlink+Jenkins实现的接口自动化测试框架V3.0

    基于python+Testlink+Jenkins实现的接口自动化测试框架V3.0 目录 1. 开发环境2. 主要功能逻辑介绍3. 框架功能简介 4. 数据库的创建 5. 框架模块详细介绍6. Tes ...

  6. 阿里云Centos7.6上面部署基于redis的分布式爬虫scrapy-redis将任务队列push进redis

    Scrapy是一个比较好用的Python爬虫框架,你只需要编写几个组件就可以实现网页数据的爬取.但是当我们要爬取的页面非常多的时候,单个服务器的处理能力就不能满足我们的需求了(无论是处理速度还是网络请 ...

  7. 在阿里云Centos7.6上面部署基于Redis的分布式爬虫Scrapy-Redis

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_83 Scrapy是一个比较好用的Python爬虫框架,你只需要编写几个组件就可以实现网页数据的爬取.但是当我们要爬取的页面非常多的 ...

  8. scrapy——7 scrapy-redis分布式爬虫,用药助手实战,Boss直聘实战,阿布云代理设置

    scrapy——7 什么是scrapy-redis 怎么安装scrapy-redis scrapy-redis常用配置文件 scrapy-redis键名介绍 实战-利用scrapy-redis分布式爬 ...

  9. 基于Python操作redis介绍

    (注:本文部分内容摘自互联网,由于作者水平有限,不足之处,还望留言指正.) 毕业前的最后一个学期(2016.03),龙哥结婚了.可是总有些人喜欢嘲笑别人,调侃我.当时我就理直气壮的告诉他们,等龙哥孩子 ...

随机推荐

  1. PHP递归算法的一个实例 帮助理解

    递归函数为自调用函数,在函数体内直接或间接自己调用自己,但需要设置自调用的条件,若满足条件,则调用函数本身,若不满足则终止本函数的自调用,然后把目前流程的主控权交回给上一层函数来执行,可能这样给大家讲 ...

  2. Web应用的组件化(二)——管控平台 #7

    Web应用的组件化(二) 管控平台 在上一篇中我们提到了组件化的大致思路,这一篇主要讲述在这么做之后,我们需要哪些外围手段去管控整个开发过程.从各种角度看,面对较大规模前端开发团队,都有必要建立这么一 ...

  3. android AsyncTask介绍 转载

    http://www.cnblogs.com/devinzhang/archive/2012/02/13/2350070.html AsyncTask和Handler对比 1 ) AsyncTask实 ...

  4. Hibernate分页查询小结

    通常使用的Hibernate通常是三种:hql查询,QBC查询和QBE查询: 1.QBE(Qurey By Example)检索方式 QBE 是最简单的,但是功能也是最弱的,QBE的功能不是特别强大, ...

  5. 读取cc2530节点的设备类型、协调器、路由器、终端。

    建立网络.加入网络流程分析 协调器节点:在1-10  实验8 网络通信实验2 组播通信中 while(MSGpkt) { switch(MSGpkt->hdr.event) { case ZDO ...

  6. 制作windows镜像

    下载包含windows驱动的iso: http://222.186.58.77/virtio-win-0.1-30.iso?fid=kF46uzxlPMrgvLDErP0ohhZYwAUASLoCAA ...

  7. CentOS新增开机启动项

    编辑rc.local文件 vi /etc/rc.d/rc.local 例如 #!/bin/sh # # This script will be executed *after* all the oth ...

  8. dom元素循环绑定事件的技巧

    以前总觉得自己写的代码不太规范,尤其是写原生的时候.举个例子: 要为页面上所有".a"的元素绑定事件,当然了用jquery很方便:$('.a').bind("click& ...

  9. windows下强大的wmic命令行工具

    windows最令网管诟病的地方就是命令行没有unix和linux强大.但这种情况正在不断改观,windows命令行也越来越强大了.其中,微软耗费大量精力打造的wmi就是一例.  获得进程ID与进程名 ...

  10. Problem - D - Codeforces Fix a Tree

    Problem - D - Codeforces  Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作 ...