我试图跳过处理分散在结果集中的几个大页面(有些超过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文档提到了这一点:
<>之前代理商=机械化uri = uri 'http://example/invalid_content_length'开始Page = agent。获取urirescue Mechanize::ResponseReadError => ePage = e.force_parse结束之前内容长度问题
某些站点返回不正确的内容长度值。与浏览器不同,mechanize在内容长度报头与响应长度不匹配时引发错误,因为它不知道是连接问题还是不匹配是服务器错误。
所引发的错误Mechanize::ResponseReadError可以根据内容类型转换为已解析的Page、File等:
换句话说,虽然head
可以提供帮助,但它不一定会给你足够的信息来让你跳过大页。您必须调查您正在爬行的站点,并了解其服务器如何响应。