我正在尝试使用Ruby和Nokogiri来抓取Waitrose & Partners的“新鲜和冷藏”产品。
为了加载更多产品,我需要单击“加载更多...”,这将动态加载更多产品,而无需更改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
答案 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不再受支持。