分享 Ruby 的爬虫世界

afly · 发布于 2016年12月03日 · 最后由 forecho 回复于 2017年4月24日 · 7190 次阅读
2116
本帖已被设为精华帖!

引子

人人争说大数据,我先做个小爬虫。

哪家工具强?

人肉搜索

先google,再翻书,github里探一探,论坛、知乎Q群走一遭

结论:python风头劲,ruby少人问。

不服!

http client

要想爬,先上路。

ruby社区里的http牌老司机可真不少,DSL手法个个好,用了就别想跑

总的来讲,这些库封装了http协议的诸多功能,诸如:form parameters, file uploads and custom body entities、gzip、Basic Authentication natively、timeout、redirect、cache etc.

可惜 http client 生来只认http,不识html。多用于做API的客户端,或者json爬虫,譬如:

WEB crawl

不识html? 不要紧,老司机给你造。

nokogiri神器在手,百万网页任你爬,不但如此,你还可以在锯子上玩各种花式爬:

开着http client上了路,拿出锯子滤信息,美女照片哗哗哗...停!我要和美女打个招呼

web interact automation

要想和美女互动,form这个码头必须拜

Mechanize automatically stores and sends cookies, follows redirects, and can follow links and submit forms

信息已发送,美女不回复...why?

你可真是老司机,现在是啥年代,开一辆上世纪的老奔驰(服务端渲染)就想泡到妞?现在车上不装个js平板(客户端渲染),你也好意思上路?

Web Browser Automation

javascript是个棘手的问题,因为它不是html这类文本(常),而是代码(变)。然而爬虫只吃文本,所以必须先要想法将代码执行,变成文本。好比,你要吃包子,你妈拿给你一包面粉,一块肉,一个菜谱,一口锅,来,自己造。

selenium 1

http://www.seleniumhq.org/

类似的困难在WEB界面自动化测试中也存在,selenium 是解决这类问题的一个test suit,其原理是:"当浏览器启动时,向其中注入javascript,从而使用这些js来驱动浏览器中的AUT(Application Under Test)..." 嗯,听起来好复杂,而且还要安装一个真实的浏览器! (实质上,就是selenium为浏览器提供一个特别扩展或插件,从而允许selenium的测试脚本可以对浏览器的内部对象进行操纵)

phantomjs

http://phantomjs.org

除了测试场景,近年来兴起的spa应用同样面临这类问题,即google等搜索引擎无法收录这类客户端渲染网页。咋办,有老司机提出:开发一个headless browser,当google等来访问时,就将请求重定向给它,由其生成静态页面后,再返还给google.

headless browser,所谓无头浏览器,就是不要脸:)。就是网页的渲染只在内存中进行,而并不输出到输出设备,譬如屏幕(所以你可以按需换头,譬如输出为html文件,屏幕截图等等)。

phantomjs就是这样一个专供程序员使用的不要脸浏览器,其实质上是基于WebKit引擎的一组 JavaScript API封装,从而方便程序员们去程序化操纵浏览器中的各类对象

web driver

以上的解决方案都是典型的太监方案。不过太监热情太高,终于能感动皇帝。

假如能通过调用浏览器原生API以直接驱动浏览器,岂非更好!

WebDriver正是这样一个项目:它通过原生浏览器支持以直接控制和操纵浏览器,并且可利用操作系统级的调用模拟用户输入。重要的是,它获得了来自浏览器厂商的原生支持(WebDriver 提供FirefoxDriver、InternetExplorerDriver、OperaDriver、 ChromeDriver等以及AndroidDriver、IPhoneDriver等移动应用测试)。

实质上,WebDriver更类似于一个浏览器无关性API集(类似于ODBC或DOM),也不与任何测试框架进行绑定,事实上今天它已成长为一项w3c标准 https://w3c.github.io/webdriver/webdriver-spec.html

selenium 2(web driver)

终于,Selenium 和 WebDriver 两个项目合并了,即 Selenium 2 ,它既支持 Selenium API ,又支持 WebDriver API,集api、工具、环境于一体。 Selenium本身虽然是java编写,但它提供各种语言绑定,譬如Selenium-WebDrive for ruby

换句话,老司机们不用换车,也能使用ruby + selenium2 搞定使用js客户端渲染的网页了。

然而,这还不够。

watir

http://watir.github.io/

watir是和selenium类似的工具,它早期使用IE-only implementation(本质上是一个封装了MS COM(Component Object Model)接口的Ruby类库,IE的COM接口允许程序访问IE浏览器的文档对象模型等)。 随着WebDriver的兴起,出现了Watir-WebDriver项目,是完全基于Ruby语言开发的WebDriver API 封装(不是Selenium-WebDrive for ruby binds),最终,2016年8月Watir和Watir-WebDriver两项目彻底合并,形成了足以对抗selenium的另一个完整生态平台。

why watir?去看看watir的示例...

老司机最爱ruby,车慢不要紧,驾车姿势要酷炫!

capybara

https://github.com/teamcapybara/capybara

最后,capybara,一个用户接受度测试框架(Acceptance test framework),同样使用ruby开发,rails应用界面测试的标配,同样必须支持browser automation。当前它支持如下后台实现:

  • rack::test: 缺省,不支持js
  • capybara-webkit: 使用QtWebKit引擎(类似于python社区的splash),支持js,但因为并未整个装入浏览器,故速度显著快过selenium,然而兼容性方面则不如webdriver
  • Poltergeist (PhantomJS) 相比于capybara-webkit,no qt ,no X server
  • selenium-webdriver: 完整的浏览器支持,当然速度....

pincers

提一下这个,似乎也不错,支持jquery query interface :)

小结

绕了一大圈,我的小爬虫在哪呢?

等我定一个小目标先

附录

烂尾起高楼,待续...

共收到 24 条回复
2116

爬虫没有窝正常,居然没有大数据节点!😬

3464

还有并发控制,验证码识别😁

3873

http://productchaseapp.herokuapp.com/ 的爬虫就是HTTParty + Nokogiri写的

主要是当时只会Ruby....

De6df3 huacnlee 将本帖设为了精华贴 12月03日 20:31
De6df3 huacnlee 如何在爬虫中运行网页中的 JavaScript 中提及了此贴 12月03日 20:32
2116

@shiny 小爬虫还没长大,并发控制之类,等等等等... 验证码识别,好大的坑,有没有开放的云服务?付费的也行😑

17580

以前用watir做自动化发帖时,也要涉及到验证码识别,写了个对接打验证码平台的gem, 也就是对接人肉打码的,比机器识别靠谱,https://github.com/seaify/confirmation_code

6864

https://github.com/httprb/http 用过这个写爬虫,遇到两个问题:

  • 貌似没有日志,RestClientFaraday 都有日志功能,可以把实际发送的请求写到日志中,可以检查请求的格式、参数是否正确。
  • 貌似不能自动处理压缩过的响应,比如这个地址 http://www.bilibili.com/index/index-icon.json 返回的就是 gzip 压缩过的响应。最后还是用 net/http 解决的。

不知道有没有遇到类似问题的同学,欢迎分享解决方案。

3464

#6楼 @afly 验证码识别主要分两类。一类是程序自动识别,一类是召唤人肉云 😁

简单的验证码可以用 tesseract 来 OCR 就可以了。复杂点的需要自己针对专门的验证码做识别算法。另外不知道百度 OCR 之类的云服务咋样,没试过。

人肉的搜「云打码」有好多类似平台。

26252

一直想做一个网站数据爬虫,减去每天手动更新的困扰,这一下突然仿佛所有的秘籍和套路一下摆在面前,真是太幸福感了

2973

爬虫我只服 mechanize

3753

#11楼 @small_fish__ mechanize遇到纯js页面就再见了,而且很多平台现在的反爬技术很强,当你打开页面没有访问页面里的静态资源 没有js计算出来的密钥放到cookie里的时候 直接判定你是爬虫弹窗输入验证码 不停弹

3255

我来补充一个感觉挺有用的库 parallel

对于代码的并发执行进行封装,可以选择开多个进程(充分利用多核),多个线程(可以加速阻塞 IO多的代码执行), 还能结合 ruby-progressbar 显示预计运行的时间。

# Doing stuff | ETA: 00:00:02 | ====================               | Time: 00:00:10

前几天收集数据需要发 20000 个 HTTP 请求,直接把代码用 parallel 包装一下,结果数据直接交给 ActiveRecord 存数据库,不用考虑并发的各种通信和锁的问题,执行速度粗略估计是顺序执行阻塞的操作的十倍。(代码连 require 不到 20 行)。

虽然 Ruby 性能相比较其它语言差一点,但是大部分应用代码瓶颈还是 IO,CPU 很少满载,合适的并发执行带来的效率提升是惊人的。

做爬虫 Python 相关的库更加丰富,但是对于简单的数据爬取,parallel + Nokogiri, 加上 Ruby 语言,简直不能更棒。

8352

可以试一下爬亚马逊商品的价格

29615
python真的好玩吗 
465

LS说的都玩过,公司其中一个业务就要用到爬虫,自己的个人项目不少也要用到爬虫。遇到的问题有:动态加载(分析JS代码、Selenium2大杀器)、IP限制(挂各种代理[免费收费]、甚至树莓派控制ADSL路由重启获取动态IP...)、用户登录(网页的/ APP API加密破解),语言用过Python/Ruby/Nodejs。现在一些简单网页解析爬虫就用js写因为可以很快(cheerio jquery like),复杂一些要做任务调度的就Python或Ruby,团队里也有大牛用Elixir,膜拜膜拜

2116

验证码的问题,思考了一下,估计可归结为如下三方面:

  1. 静态验证: 典型代表即图片验证码。缺陷是,验证码是由算法生成且必须局限于能被人类识别的边界(字母+数字),因此,机器自然可以从人类的识别模式出发,再辅之以足够多的样本进行比对和学习,只要计算力足够强大,就能轻松破解。故对图片验证码的反破解思路之一即剔除模式以加大计算边界,譬如 12306 式的看图选择 或者 问答题式的验证。

  2. 动态验证: 但对于云打码这类平台,再复杂的看图答题也无济于是。问题出在验证码是以静态的图片、文字或录音等方式存在的,爬虫可以轻松的把它们传送至高效率的人工平台(也许那里有什么超级神器也不定)获得破解结果。基于此,反破解的思路就是将验证过程动态化,譬如 https://world.taobao.com/markets/all/sea/register ,必须要求先做一个手势动作,然后才可获取验证码图片。这是欺负爬虫无法模拟这一动作或事件吗?嗯,这个有待研究...

  3. 物理验证: 以上验证变来变去,终究是内存里的战斗。最简单的反爬方式就是引入一个外部物理设备做验证,譬如短信验证,手机扫码,然而据说手机机器人集群也已产业化,无非多养几个手机号,这个,谁来详细爆个料😍 ...

我想,未来,一律实名注册,集中认证,虹膜扫脸,大约可灭此爬虫矣

4789

python的scrapy已经很成熟,且经过无数验证,上手还快

2116

关于并发、并行、分布式等可扩展性问题,其实更多是爬虫之外:

  1. 并发:IO与cpu的同步问题,@oa414 提供了一个不错的库 parallel ,够用
  2. 并行: 这个涉及到具体的任务分解,但爬虫一般只涉及数据抓取,独立性强,似乎问题不大
  3. 分布式: 多台机器之间的调度与管理,不知有没有从chief puppet等网管项目中抽取出来的框架,可以即插即用。不过据说ansible 项目可以无agent部署,又是python占了上风😾

@reducm "IP限制(挂各种代理[免费收费]" 这个,可否详细的讲一讲

465

@ghjcumt2008 scrapy is awesome!

@afly IP限制,比较常见是一段时间内同一IP访问次数限制,另外有些资源还会有一些更复杂的登录令牌与IP绑定的限制,这个与资源方的风险防范机制有关。理论上,爬虫越能模拟到真实用户行为,越难防范,落实到爬虫的实现,就是各种细节上的调节。如你所说大量的手机号是有必要的,我们的其中一个项目就是开了一堆手机号和买了一堆低配红米,做到了控制短信,还有更新登录信息到服务器,还有在Android利用辅助权限上做一些模拟行为操作😅 。另外代理的话就比较好理解了,做成一个代理IP池,一个IP被封了另一个IP再上,本质就是需要很多可用的IP代理。免费的话可以爬各大代理网站提供的免费代理:

  1. http://www.xicidaili.com/
  2. http://ip.izmoney.com/
  3. http://www.kuaidaili.com/
  4. http://www.proxy360.cn/
  5. http://www.goubanjia.com/

这里有个好玩的就是他们也有一定的防范机制,鸡生蛋生鸡😂 ,比较奇葩的是goubanjia进去是等一会儿才会变出真正的端口...

第二种方法就是购买他们的收费代理。有了一堆IP后,我们的做法是搭一个专门的小服务,小服务会提供接口,把代理IP拿去test target,另外也有接口返回一堆可用的IP。

当然了,如果还是感觉代理质量不太好的话(延迟、大量不可用),土豪的话可以买一堆低配的云IP服务器,可以找些切换IP比较快的服务(阿里云好像有)。最后我们还想了个方案,就是把家里空余的宽带资源也可以提供出来,用树莓派做个远程控制,IP被封了就重新上线获取新的IP,不过这个方案还没用到(上面两个已经够用了)...

4584

还没有测试过性能方面?

29931

使用restClient+nokogiri+watir+phantomjs ,ruby多线程顺畅写爬虫(不需验证码的).😎

4938

任务管理简单点可以用sidekiq,worker放在docker里面,集群部署不是啥问题~

96

nightmare (electron) 前来报到

30210

其实简单的数据爬取火车头,集搜客,神箭手,造数(不是打广告)之类的第三方平台就可以解决了,不仅用很少的代码或者不写代码就能实现,而且很快就能得到想要的数据,看最近的一些爬虫热潮,有些很简单的根本用不着代码,还非要自己写,而且费时间,有其它平台为什么不使用?怪象,至于大规模的数据爬取需求,分布式,并行……有多少用到的人。先考虑规模再看实现方式。

8352
30210YingJie 回复

其实我也想用你上面提到的第三方平台,但是我没找到我需要的,我是想爬中国亚马逊电子书的价格信息

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册