How to collect content form Web

How to collect content form Web

4035ddfe11dbb2afc4e683b1bc6ac68f?s=128

Jason Lee

July 27, 2012
Tweet

Transcript

  1. 如何编写数据采集器 Jason Lee 12年7月27⽇日星期五

  2. Nokogiri Python Ruby Regexp 12年7月27⽇日星期五

  3. Hello world require "nokogiri" require "open-uri" doc = Nokogiri::HTML(open("http://www.cnbeta.com"),nil, "gbk")

    doc.css(".newslist .topic a").each do |a| puts "#{a.text} - #{a.attr("href")}" end 摩托罗拉移动总部将搬⾄至芝加哥 涉及3000⼈人 - /articles/199038.htm 步步惊⼼心!解密Google千兆宽带如何降低成本 - /articles/199037.htm 不肯服输 苹果成功申请暂缓执⾏行道歉裁决 - /articles/199035.htm [最新]摩托罗拉Android机型在德国被禁售 - /articles/199034.htm Windows Phone 8版IE 10新特性侧漏 - /articles/199033.htm [视频]⽇日本研发新⼀一代商店付费⽅方案BacaryScan - /articles/199032.htm ⾕谷歌搜索结果⻚页⾯面再改版 左侧全留⽩白 - /articles/199031.htm [视频]预留摄像头位置 ⾕谷歌Nexus 7平板拆机视频曝光 - /articles/199029.htm [图]苹果2006年iPhone原型设计曝光 - /articles/199028.htm 你所不了解的中国字库产业链 - /articles/199027.htm ..... 12年7月27⽇日星期五
  4. Problems • 编码 • 需要登陆 • ⻚页⾯面请求频率限制 • 不规则的内容结构 •

    Javascript 产⽣生的内容 • 列表到⼦子⻚页内容 • 图⽚片以及其他⼀一些资源⽂文件 • 需要 POST 请求才能访问的⻚页⾯面,⽐比如搜房⺴⽹网 Asp.net 的翻 ⻚页; 12年7月27⽇日星期五
  5. 编码问题 Nokogiri::HTML(open("http://www.cnbeta.com"),nil, "gbk") GB2312 Nokogiri::HTML(open("http://www.cnbeta.com")) UTF-8 12年7月27⽇日星期五

  6. 需要登陆的⻚页⾯面 12年7月27⽇日星期五

  7. require 'mechanize' agent = Mechanize.new agent.get("http://www.douban.com/accounts/login") form = agent.page.forms.first #

    email form.fields[2].value = "huacnlee@gmail.com" # password form.fields[3].value = "jiubugaoshuni" form.submit agent.get("http://www.douban.com/accounts/") puts agent.title https://github.com/tenderlove/mechanize 12年7月27⽇日星期五
  8. 访问频率限制 • 设定 200ms 延迟每次⻚页⾯面请求; • ⽤用 Memcached 控制全局的⻚页⾯面下载频率; class

    GlobalFetcher def self.read(url) return false if !self.allow? self.hint open(url).read end def self.hint Rails.cache.increment("global_fetcher_#{Time.now.strftime("%Y%m%d%H%M")}" , 1) end def self.count Rails.cache.read("global_fetcher_#{Time.now.strftime("%Y%m%d%H%M")}" ).to_i || 0 end def self.allow? self.count < 40 end end 每分钟 40 次请求 12年7月27⽇日星期五
  9. 不规则的结构 <div id="info"> <span><span class="pl">导演</span>: 盖瑞·罗斯</span><br/> <span><span class="pl">编剧</span>: 苏珊·科林斯 /

    ⽐比利·雷 / 盖瑞·罗斯</span><br/> <span><span class="pl">主演</span>: 詹妮弗·劳伦斯 / 乔什·哈切森</span><br/> <span class="pl">IMDb链接:</span> <a href="...">tt1392170</a><br> </div> <div id="info"> <span><span class="pl">导演</span>: 盖瑞·罗斯</span><br/> <span><span class="pl">主演</span>: 詹妮弗·劳伦斯 / 乔什·哈切森</span><br/> <span><span class="pl">语⾔言</span>: 英⽂文 / 法语</span><br/> <span><span class="pl">国家</span>: 美国</span><br/> <span class="pl">IMDb链接:</span> <a href="...">tt1392170</a><br> </div> Sometimes like this: 12年7月27⽇日星期五
  10. AJAX 内容 12年7月27⽇日星期五

  11. ⼦子⻚页⾯面 doc = Nokogiri::HTML(open("http://www.cnbeta.com"),nil, "gbk") doc.css(".newslist .topic a").each do |a|

    fetch_content(a.attr("href")) end def fetch_content(path) doc = Nokogiri::HTML(open("http://www.cnbeta.com#{path}"),nil, "gbk") ... end 12年7月27⽇日星期五
  12. 需要验证码? 这是⼤大难题... 12年7月27⽇日星期五

  13. 技巧 • 通过 RSS 或其他 API 关注内容更新; • 下载⻚页⾯面的⽅方法加⼊入 caching

    提升下次⽆无意访问到同样⻚页⾯面的 速度,例如: open-uri-cached; • 伪造 http_referer,以破解某些⽐比较弱的图⽚片防盗链; • 设定登对⺴⽹网站级别的访问延迟控制(Memcached),以防⽌止 速度过快被屏蔽 IP; • 通过 CSS Selector + Regexp 采集⼀一些⽆无规则的结构; • 仔细分析,猜测,找出⻚页⾯面/URL 规则,拿到⼀一些隐藏的内 容; 12年7月27⽇日星期五
  14. 其他学习资源 • http://railscasts.com/episodes/173-screen-scraping-with- scrapi • http://railscasts.com/episodes/190-screen-scraping-with- nokogiri • http://railscasts.com/episodes/191-mechanize 12年7月27⽇日星期五

  15. End http://huacnlee.com 12年7月27⽇日星期五