抓取 - 加载动态按钮

Scraping - Loading dynamic buttons

我正在尝试使用 Ruby 和 Nokogiri 对 Waitrose & Partners 的 "Fresh & Chilled" 产品进行网络抓取。

为了加载更多产品,我需要单击 'Load More...',这将动态加载更多产品,而无需更改 URL 或重定向到新页面。

如何 'click' "Load More" 按钮加载更多产品?

我认为这是一个动态网站,因为在单击 "Load More..." 按钮后动态加载项目并且 URL 根本没有改变(因此没有分页可见)

这是我迄今为止尝试过的代码,但我无法加载更多项目。我的猜测是 DOM 正在自行加载,但您实际上不能单击该按钮,因为它代表调用 javascript 方法来加载其余项目。

require "csv"
require "json"
require "nokogiri"
require "open-uri"
require "pry"

def scrape_category(category)
  CSV.open("out/waitrose_items_#{category}.csv", "w") do |csv|
    headers = [:id, :name, :category, :price_per_unit, :price_per_quantity, :image_url, :available, :url]
    csv << headers
    url = "https://www.waitrose.com/ecom/shop/browse/groceries/#{category}"
    html = open(url)
    doc = Nokogiri::HTML(html)
    load_more = doc.css(".loadMoreWrapper___UneG1").first
    pages = 0
    while load_more != nil
      puts pages.to_s
      load_more.content # Here's where I don't know how to click the button to load more items
      products = doc.css(".podHeader___3yaub")
      puts "products = " + products.length.to_s
      pages = pages + 1

      load_more = doc.css(".loadMoreWrapper___UneG1").first
    end
    (0..products.length-1).each do |i|
      puts "url = " + products[i].text
    end
    load_more = doc.css(".loadMoreWrapper___UneG1")[0]

    # here goes the processing of each single item to put in csv file
  end
end

def scrape_waitrose
  categories = [
    "fresh_and_chilled",
  ]

  threads = categories.map do |category|
    Thread.new { scrape_category(category) }
  end

  threads.each(&:join)

end

#binding.pry

Nokogiri 是一种解析方式HTML。它是 Ruby 相当于 Javascript 的 Cheerio 或 Java 的 Jsoup。这实际上不是 Nokogiri 问题。

您感到困惑的是解析 HTML 的方式和收集 HTML 的方法,这些都是通过网络传送的。重要的是要记住许多功能,例如您的按钮点击,都是由 Java 脚本启用的。如今,许多网站(例如 React 网站)完全由 Javascript 构建。

所以当你执行这一行时:

doc = Nokogiri::HTML(html)

这是您必须关注的html变量。您的 html 与我在浏览器中从同一页面查看的 html 不同

为了进行任何类型的可靠网络抓取,您必须使用将执行Java脚本文件的无头浏览器。在 Ruby 术语中,这曾经意味着使用 Poltergeist 来控制 Phantomjs,Webkit 浏览器的无头版本。当 Puppeteer 和 headless Chrome 到来时,Phantomjs 变得不受支持。