【问题标题】:How do I do paginating in Nokogiri when the number of pages is not readily available?当页数不可用时,如何在 Nokogiri 中进行分页?
【发布时间】:2013-11-17 09:41:48
【问题描述】:

我正在尝试学习如何构建一个可以下载到本地目录的自定义屏幕抓取工具,并且我正在关注 Danny Ngyuen 的“The Great Bastards Guide”。我有一个书中没有解决的问题:如果我要抓取的页面在其分页方案中没有可见的最后页码怎么办?

一些网站会限制在其结果中显示的页面数量,直到您接近尾声,例如 Google。当last_page_number 在主索引上不可见时,我将如何定义它。或者,当我只有一个下一页链接时,是否有更好的方法让 Nokogiri 通过分页?

require 'rubygems'
require 'nokogiri'
require 'open-uri'
require 'fileutils'
BASE_URL = 'http://explore.data.gov'
BASE_DIR = '/catalog/raw/?&limit=100&page='
LOCAL_DIR = 'data-hold/datagov-pages'

FileUtils.makedirs(LOCAL_DIR) unless File.exists?LOCAL_DIR

# get metainfo from first page:
page = Nokogiri::HTML(open(BASE_URL+BASE_DIR + '1'))

# write the HTML for page 1 to disk
File.open("#{LOCAL_DIR}/1.html", 'w'){|f| f.write(page.to_html)}

last_page_number = page.css("a.end.lastLink.button")[0]['href'].match(/page=(\d+)/)[1].to_i

puts "Iterating from 2 to #{last_page_number}"

for pg_number in 2..last_page_number do
  puts "Getting #{pg_number}"
  File.open("#{LOCAL_DIR}/#{pg_number}.html", 'w') do |f| 
    f.write( open("#{BASE_URL}#{BASE_DIR}#{pg_number}").read )
  end
end

【问题讨论】:

    标签: ruby-on-rails ruby pagination nokogiri


    【解决方案1】:

    如果页面数不是一个已知值,就像在您的示例中的网站上一样,那么您已经决定是尝试阅读无限数量的页面,还是将搜索限制为 n 页。

    Google 实际上可能能够返回一千页或更多特定搜索的页面,但第五个之后的页面的价值是非常值得怀疑的。因此,对于 Google,将您的抓取限制在前 n 个页面。

    对于所有页面都很有趣且没有已知结束页面的网站,您必须手动导航到最后一页,并挑选出您的代码“地标”,然后搜索您检索的每个页面,因此您知道何时到达。

    或者,您可以从第 1 页开始,并不断增加,直到您的代码无法获取页面。为此,您必须将“获取页面”代码包装在异常处理程序中,这样当它失败时您的代码不会崩溃,并且您可以优雅地退出。

    【讨论】:

    • 在我的理论示例中,里程碑是没有下一页按钮。我在想我会为下一页包含 css 选择器,然后循环直到它不再可见。这是解决此问题的好方法吗?如果是,您将如何更改上述代码以正确循环但仍保持抓取和磁盘写入过程。
    • 是的,这种策略会奏效。如何实现,你自己去琢磨。这并不难。
    【解决方案2】:

    通常当您尝试访问不存在的页面时,您会收到 404 HTTP 状态。您可以增加页码,直到出现 404 错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      • 2019-10-02
      • 1970-01-01
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多