数据抓取的艺术(三):抓取Google数据之心得

 本来是想把这部分内容放到前一篇《数据抓取的艺术(二):数据抓取程序优化》之中。但是随着任务的完成,我越来越感觉到其中深深的趣味,现总结如下:

   (1)时间
     时间是一个与抓取规模相形而生的因素,数据规模越大,时间消耗往往越长。所以程序优化变得相当重要,要知道抓取时间越长,出错的可能性就越大,这还不说程序需要人工干预的情境。一旦运行中需要人工干预,时间越长,干预次数越多,出错的几率就更大了。在数据太多,工期太短的情况下,使用多线程抓取,也是一个好办法,但这会增加程序复杂度,对最终数据准确性产生一定影响。
     所以,千万不能看不起小小的调优,那怕只是0.02秒一次的改进,对于上万乃至千万级别的数据量而言,都可以节省数小时甚至数天的时间,同时也能在某种程度上降低出错的概率。于是,我得出一个原则:“程序优化要力求极致”。
     这是“软”的因素。

   (2)效率
      呵呵,效率可以被视为是时间的另一种说辞,虽然这种说法并不全面。在这里我所谓的效率,指的是I/O效率。一旦算法优化已经完善,那么还有什么可以提高效率以缩短程序完成的时间呢?这回抓取,我使用的是SSD硬盘,与实验室的机械硬盘相比(可惜用的是笔记本),速度得到了明显的提升。
     我感觉以后处理大规模数据(或“大数据”),需要使用内存数据库。首先,使用数据库而非Excel就已经能够提高效率,如果再采用内存数据库的话,效率将得到更大幅度的攀升。当然,如果你机器内存足够大的话,可以试试Redis。
     SSD硬盘与内存数据库是特别重要的两个方面。但我们也不能忽略CPU,一个好的CPU就是一颗“强劲的心”,但是笔记本的CPU一般都做过“调优”(想想吧:有限的电力,为了延时,只好吃一口“蓝色小丸药”),我觉得I3处理器性能有些低下,如果不是I5+还不如直接用奔腾双核结构。当然最好是运行在台式机、工作站、服务器甚至云系统中。嘿嘿,下次我要试试Sae。
     这是“硬”的因素。

   (3)了解你的对手
     常言道,知己知彼百战不殆。做数据抓取,最重要的就是了解你的对手。这一轮,我很倒霉,我碰到了Google姐,由于我的数据只能从Google上析出,所以没的选择,不过虽说她也把我折腾地够呛,但最终我还是享受到了“神秘的”幸福。
     这是“人”(目标对手)的因素。
     八卦一下我和Google姐一夜大战的六个回合吧。
     第一回合,简单地使用urllib2或其它库是不行的,我的血泪史说明,搜索超不过8个Google就强行和你失去连接了。重新搜这几个还可以,但接着第8个往后走,她就又不干了,还是不能连接。姐姐一脸坏笑地看着我,就这点小把戏,还想过来扒我裤子?我十分汗颜,责怪自己没能正确估计出她那雄壮的腰围。
     第二回合,我开始设计欺骗Google。由于人类访问网站,不会有极短而均匀的点击行为,所以我设计了一个小函数,每次搜索完毕,随机暂停1~3秒,这是在模仿人的访问模式。不幸再次降临到我身上,姐姐的坏笑依旧,我也没能触动到她的一根毫毛。
     第三回合,我生气了。我准备上代理,我的战术很简单,弄一大堆代理站成一队,排得一眼望不到边,失去连接我就换一个代理,再失去就再换,吓死她!结果这条路仍没走通,这种硬碰硬的方式不是好方式,姐姐其实是过来人,从小吓大的,这招没用:一方面是我找到的可用代理IP实在有限,根本不够换的;另一方面,代理的引入大大增加了程序出错的可能性,因为代理本来就不都靠谱。好几次,不是Google断掉的而是代理跑着跑着给断的。
     第四回合,我没气可生了。我开始深入研究,静下心来耐心学习这个领域的知识,仔细欣赏、研究Google这个熟女。功夫不负有心人,我找到了终极解决方案:浏览器。不必再模拟手工行为(Mechanize),咱就直接用浏览器访问,看她还有什么话说。其实这样的方法很多,核心就是使用测试工具。所以你也可以使用selenium或Windmill,也可以使用QT+Webkit等等就不一一列举了。当然,我用的是Selenium+Phantomjs+BeautifulSoup,后来想想也不用BS,直接正则算了,但毕竟BS比较简单哈。
     第五回合,我编写好程序,进行优化,特意选择深夜悄然开始执行。我用的校园网,晚上网速极快,所以嗖嗖地抽取出结果,但有个问题,就是Google对单IP短时持续访问请求是有限制的,这个限制不论是蜘蛛还是人都绕不开,她会证给你一个填写验码的证明页面,上书“不能未婚先孕”,到街道办开了证明才能让你继续。唉,对此,一开始,我太年轻,真没什么办法,只能在程序中识别这个页面,然后保存结果退出。再重新启动继续这个断点接着执行。不过由于每隔70、80个就会因验证码页面停掉一次,我的抓取速度一直不高,因为需要手工干预。
     [虚拟第六回合,我用一个新线程执行抓取,当这个线程遇到验证码时,保存、退出并回馈断点参数,然后带入参数重启一个新的线程。时间原因,还没如此实现。]
     第六回合,较长的抓取时间,我在傻傻等待,时不时断点续抓一次。我受不了了,我开始做点其他的事情,比如浏览新闻、听听音乐、看看电影什么的。终于,我发现,竟然碰不到验证码页面了。这点十分惊喜,仔细研究了这个过程,我得出结论,抓取时其他程序对抓取程序网速的影响,正好让Google认为这似乎就是人在搜索,所以从95个左右开始,到最后的152个的共词搜索,还是那个程序,但由于我的其他休闲活动导致后半程一次都没有遇到验证码。Oh Yeah~神马重启一个新线程,NND都是浮云,一边爬取数据一边轻松生活才是王道。(只是别因下片把网速全占满了,使你的抓取程序一直处于一个等待状态,就像《潜伏》最后一幕一样,翠平抱着孩子一直在等待一个永远不能归来的人)。所以要向普天下的男人们大声说:不要那么直接,一上来就只知道抓,一起多看看电影、多听听歌,效果会更好!难道不是么?

      最后,我站在高岗上,手握着Google的内裤,让它尽情随风舞动......
      这就是技术,这也是生活!

时间: 2024-11-01 05:19:05

数据抓取的艺术(三):抓取Google数据之心得的相关文章

数据抓取的艺术(二):数据抓取程序优化

      续前文:<数据抓取的艺术(一):Selenium+Phantomjs数据抓取环境配置>. 程序优化:第一步开始: for i in range(startx,total):     for j in range(starty,total):         BASE_URL = createTheUrl([item[i],item[j]])         driver.get(BASE_URL)         driver = webdriver.PhantomJS()    

数据抓取的艺术(一):Selenium+Phantomjs数据抓取环境配置

数据抓取是一门艺术,和其他软件不同,世界上不存在完美的.一致的.通用的抓取工具.为了不同的目的,需要定制不同的代码.不过,我们不必Start from Scratch,已经有许多的基本工具.基本方法和基础框架可供使用.不同的工具.不同的方法.不同的框架的特点也不同.了解这些工具.方法和框架是首要任务,接下来就需要明白它们的差异都在哪里.什么情境该用什么东东,最后才是析出规则.编写代码.运行程序来抓取数据.所以说,其实数据抓取的学习路线,不但很长而且很杂.     为了一个特定的目的,我需要爬取G

如何抓取天猫和淘宝的运营数据?

对通用网站的数据抓取,比如:谷歌和百度,都有自己的爬虫,当然,爬虫也都是有程序写出来的.根据百度百科的定义:网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁,自动索引,模拟程序或者蠕虫.不过,淘宝为了屏蔽网络爬虫对自身数据(例如商品价格.月销量.收藏量.评价.月成交记录等等)的抓取,往往是采取一种名叫Ajax的技术,在网页加载完成后,再次加载这些数据,所以通用的网络爬虫抓取技术对抓取淘宝的这些数据是无效的.针对淘宝

php-curl抓取淘宝首页抓取不到。

问题描述 curl抓取淘宝首页抓取不到. 列表页面"> 这是我的代码,抓取淘宝一直抓取不到. 解决方案 curl得到的内容和你浏览器查看源代码后得到的一样,js动态添加的内容和ajax动态加载的无法获取 解决方案二: 数据都是js 动态生成的,你获取的只是代码. 解决方案三: 淘宝应该有防抓取设置 一般是通过判断请求来源来防止抓取 你可以在浏览器中访问时抓一下包 分析一下它的请求头数据 模拟一下啥 解决方案四: 页面是动态生成的,你没办法直接拿到内容,

麻烦大家给你网络抓取程序 需要被抓取网页的标题内容来源存入数据库

问题描述 麻烦大家给你网络抓取程序需要被抓取网页的标题内容来源存入SQL2000数据库 解决方案 解决方案二:在网上搜网络爬虫或者网络机器人,解析网页的内容用apache的HttpClient解决方案三:htmlParse

php通过curl单独抓取网页可以,抓取多个就会出错

问题描述 php通过curl单独抓取网页可以,抓取多个就会出错 使用curl单独抓取http://jobs.hubu.edu.cn/Detail.aspx?ArticleChannelId=81&ArticleId=5722可行,但是如果抓取相同类型的一系列网站就会出错,将他们放在数组 $linkList中,分别是http://jobs.hubu.edu.cn/Detail.aspx?ArticleChannelId=81&ArticleId=5722,http://jobs.hubu.e

抓包发现 mina 服务端重复发送数据? 请问是该怎么解决?

问题描述 抓包发现 mina 服务端重复发送数据? 请问是该怎么解决? @Override public void messageSent(IoSession session, Object message) throws Exception { logger.info("---消息发送 : " + message); } messageSent方法执行了一次 , 但抓包发现 发送了两次数据 解决方案 确定是发了两次,不是两包数据?应用只发送一次,到在网络中可能有两包,或者更多包的数据

mysql表关联只取关联表中最近一条数据

问题描述 mysql表关联只取关联表中最近一条数据 表A{id,userId,logTime} 表B{id,userId,departmentId,updateTime} 表A为数据记录 表B相当于历史记录表(userId在updateTime时间之前的departmentId) 现在表A与表B关联 但是只能让表B中符合条件的最近一记录关联上 (也是updateTime在logTime之前并且最近的一条) 我是这么做的 SELECT A.id,B.userId,B.departmentId FR

网络协议-PPTP协议数据包有几个无法抓到,急~~

问题描述 PPTP协议数据包有几个无法抓到,急~~ RT,PPTP协议数据包通过Wireshark有4个无法抓到分别是:Incoming-Call-Request Incoming-Call-Reply Incoming-Call-Connected WAN-Error-Notify请问有没有大神抓到过这四个包?这四个包在哪种环境里面能够抓到?这4个数据包在整个数据包传输过程中是怎样的发包顺序呢? 现在我能抓到的包如图所示,哪怕数据包出错也没有出现"WAN-Error-Notify"&