在Mechanize (Ruby)中跳过大的页面



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

不幸的是,我找不到"content-length"属性或类似的指示符。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

Content_length during response_read:

在Mechanize源代码中,我发现读取响应时引用了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

Mechanize通常会"获取"整个页面。相反,您应该首先使用head请求来获取页面大小,然后有条件地获取页面。参见"如何在Ruby中使用mechanize执行Head请求"中的示例。

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

Mechanize文档提到了这一点:

内容长度问题

某些站点返回不正确的内容长度值。与浏览器不同,mechanize在内容长度报头与响应长度不匹配时引发错误,因为它不知道是连接问题还是不匹配是服务器错误。

所引发的错误Mechanize::ResponseReadError可以根据内容类型转换为已解析的Page、File等:

<>之前代理商=机械化uri = uri 'http://example/invalid_content_length'开始Page = agent。获取urirescue Mechanize::ResponseReadError => ePage = e.force_parse结束之前

换句话说,虽然head可以提供帮助,但它不一定会给你足够的信息来让你跳过大页。您必须调查您正在爬行的站点,并了解其服务器如何响应。

相关内容

  • 没有找到相关文章

最新更新