Ruby Mechanize 网络爬虫库返回文件而不是页面

JRP*_*ete 2 ruby mechanize object scraper

我最近一直在使用 ruby​​ 中的 Mechanize gem 编写一个刮刀。不幸的是,我试图抓取的 URL在请求时返回一个Mechanize::File对象而不是一个Mechanize::Page对象GET

我不明白为什么。我尝试过的每个其他 URL 都返回了一个Mechanize::Page对象。

有没有办法强制 Mechanize 返回一个Page对象?

fea*_*ool 5

这是发生了什么。

当您下载“普通”网页时,其标题将包含一个字段,内容类似于Content-Type text/html. 当 Mechanize 看到这一点时,它知道将页面内容解释为 HTML 并将其解析为 Mechanize::Page 对象,包括链接和表单等。

但是,如果你曾经一个链接,说“下载CSV数据”或“下载PDF”,或者在短期,任何非HTML上点击,您收到的没有一个页面Content-Typetext/html。由于 Mechanize 无法将非 html 解析为 Mechanize::Page 对象,因此会将内容打包为 Mechanize::File 对象。

您如何使用 Mechanize::File 对象取决于您要完成的任务。例如,如果您知道您访问的页面是 CSV 数据而不是 HTML,您可以像这样提取 CSV 数据:

page = web_agent.get(some_url_that_references_csv_data)
parsed_csv = CSV.parse(page.body)
Run Code Online (Sandbox Code Playgroud)

如果您想花哨,您可以编写自己的解析器,让 Mechanize 处理非 HTML 格式。如果你想走那条路,请参阅PluggableParser 上的 Mechanize 文档。但是您可以通过直接使用 Mechanize::File 对象来完成很多工作。

回应@user741072 评论的附录

另一方面,如果页面HTML 并且有人忽略了设置content-type为 HTML,您可以编写一个方法,将 html 解析器交换为默认解析器,只要足够长的时间来解析页面。这将强制解析为 HTML:

def with_html_parser(agent, &body)
  original_parser = agent.pluggable_parser.default
  agent.pluggable_parser.default = agent.pluggable_parser['text/html']
  begin
    yield
  ensure
    agent.pluggable_parser.default = original_parser
  end
end
Run Code Online (Sandbox Code Playgroud)

让我知道这是否有用。