抓取-加载动态按钮

时间:2020-03-10 23:11:08

标签: ruby web-scraping nokogiri

我正在尝试使用Ruby和Nokogiri来抓取Waitrose & Partners的“新鲜和冷藏”产品。

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

如何“单击”“加载更多”按钮以加载更多产品?

enter image description here

我认为这是一个动态的网站,因为在单击“加载更多...”按钮后会动态加载项目,并且网址完全不会更改(因此看不到分页)

这是到目前为止我尝试过的代码,但是我只能加载更多的项目。我的猜测是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

1 个答案:

答案 0 :(得分:1)

Nokogiri是一种解析HTML的方法。它是Ruby,等效于Java的Cheerio或Java的Jsoup。这实际上不是Nokogiri问题。

您所困惑的是解析HTML的方法和收集HTML的方法(通过网络传递)。重要的是要记住,Javascript启用了许多功能,例如单击按钮。如今,许多站点(如React站点)完全由Javascript构建。

因此,当您执行此行时:

doc = Nokogiri::HTML(html)

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

为了进行各种可靠的Web抓取,您必须使用无头浏览器来执行Javascript文件。用Ruby术语来说,这曾经意味着使用Poltergeist来控制Phantomjs(Webkit浏览器的无头版本)。当Puppeteer和无头的Chrome到来时,Phantomjs不再受支持。