跳过Mechanize(Ruby)中的大页面

时间:2014-07-30 15:08:47

标签: ruby mechanize mechanize-ruby

我试图跳过处理散布在结果集中的几个大页面(一些超过10MB),因为Mechanize(版本2.7.3)会抓取一系列链接。

很遗憾,我找不到内容长度'财产或类似指标。 Mechanize::FileResponse类有content_length方法但Mechanize::Page没有。

目前的方法

目前我正在呼叫页面上的content.length。当抓取其中一个大页面时,这非常慢:

detail_links.each do |detail_link|

  detail_page = detail_link.click

  # skip long pages
  break if detail_page.content.length > 100_000

  # rest of the processing
end

response_read期间的Content_length:

在Mechanize源代码中,我在读取响应时找到了a reference to content_length。查询响应属性是否可能成为解决方案?

# agent.rb extract from the Mechanize project
def response_read response, request, uri
    content_length = response.content_length

    if use_tempfile? content_length then
      body_io = make_tempfile 'mechanize-raw'
    else
      body_io = StringIO.new.set_encoding(Encoding::BINARY)
    end

1 个答案:

答案 0 :(得分:1)

Mechanize通常会“获取”整个页面。相反,您应首先使用head请求获取页面大小,然后有条件地获取页面。有关示例,请参阅“How can I perform a Head request using mechanize in Ruby”。

需要注意的是,当您执行head请求时,动态生成的资源可能没有已知大小,因此您可以获得没有大小条目的响应。请注意,在上面链接的问题的选定答案中,Google未返回content-length标头,因为它是动态生成的页面。静态页面和资源应该有标题...除非服务器由于某种原因没有返回它们。

Mechanize documentation提到了这个:

  

内容长度问题

     

某些网站返回的内容长度值不正确。与浏览器不同,当内容长度标头与响应长度不匹配时,机械化会引发错误,因为它不知道是否存在连接问题或者不匹配是服务器错误。

     

引发的错误,Mechanize :: ResponseReadError,可以转换为已解析的页面,文件等,具体取决于内容类型:

agent = Mechanize.new
uri = URI 'http://example/invalid_content_length'

begin
  page = agent.get uri
rescue Mechanize::ResponseReadError => e
  page = e.force_parse
end

换句话说,虽然head可以提供帮助,但它不一定能为您提供足够的信息以允许您跳过大页面。您必须调查您正在抓取的网站并了解其服务器如何响应。