Ruby on rails 为什么我的Ruby函数只抓取第一页而不抓取分页的页面?
我使用nokogiri在经销商网站上对大约14页的所有车辆进行网络刮取,我遇到的错误是我的代码仅在第一页上运行刮取器14次。我的代码有什么问题 从输出中可以看出,相同的车辆被一次又一次地刮伤,而不是下一页中的新车辆 Ruby版本:2.6.2 scraper.rb:Ruby on rails 为什么我的Ruby函数只抓取第一页而不抓取分页的页面?,ruby-on-rails,ruby,web-scraping,nokogiri,httparty,Ruby On Rails,Ruby,Web Scraping,Nokogiri,Httparty,我使用nokogiri在经销商网站上对大约14页的所有车辆进行网络刮取,我遇到的错误是我的代码仅在第一页上运行刮取器14次。我的代码有什么问题 从输出中可以看出,相同的车辆被一次又一次地刮伤,而不是下一页中的新车辆 Ruby版本:2.6.2 scraper.rb: require 'nokogiri' require 'httparty' require 'byebug' def scraper url = "https://w
require 'nokogiri'
require 'httparty'
require 'byebug'
def scraper
url = "https://www.example.com/new-vehicles/"
unparsed_page = HTTParty.get(url)
parsed_page = Nokogiri::HTML(unparsed_page)
vehicles = Array.new
vehicle_listings = parsed_page.css("//div[@class='vehicle list-view new-vehicle publish']") #20 cars
page = 1
per_page = vehicle_listings.count #20
total = parsed_page.css('span.count').text.to_i #281
last_page = (total.to_f / per_page.to_f).ceil #14
while page <= last_page
pagination_url = "https://www.example.com/new-vehicles/#action=im_ajax_call&perform=get_results&page=#{page}"
pagination_unparsed_page = HTTParty.get(pagination_url)
puts pagination_url
puts "Page: #{page}"
puts ''
pagination_parsed_page = Nokogiri::HTML(pagination_unparsed_page)
pagination_vehicle_listings = pagination_parsed_page.css("//div[@class='vehicle list-view new-vehicle publish']") #20 cars
pagination_vehicle_listings.each do |vehicle_listing|
vehicle = {
title: vehicle_listing.css('h2')&.text&.gsub("New", '').gsub("2021", '').gsub("With", '').gsub("Navigation", ''),
price: vehicle_listing.css('span.price')[0]&.text&.delete('^0-9').to_i,
stock_number: vehicle_listing.css('.stock-label')&.text.gsub("Stock #: ", ''),
exterior_color: vehicle_listing.css('span.detail-content')[3]&.text,
interior_color: vehicle_listing.css('span.detail-content')[4]&.text&.delete('0-9').gsub('MPG', 'unavailable')
}
vehicles << vehicle
puts "Added #{vehicle[:stock_number]}"
puts ""
end
page += 1
end
byebug
end
scraper
需要“nokogiri”
需要“httparty”
需要“byebug”
def刮刀
url=”https://www.example.com/new-vehicles/"
unparsed_page=HTTParty.get(url)
解析的页面=Nokogiri::HTML(未解析的页面)
车辆=阵列。新
vehicle_listings=parsed_page.css(“//div[@class='vehicle list view new vehicle publish'])20辆车
页码=1
每页=车辆列表.计数#20
总计=已解析的页面.css('span.count').text.to#i#281
最后一页=(总计.至页/每页.至页).ceil#14
而page虽然看起来数据是通过GET请求通过链接加载的,但实际上是通过jQuery通过POST请求加载的。
您可以通过打开浏览器开发工具的“网络”选项卡来验证这一点
如果在浏览器中输入url,则会发出一个请求:
- 获取初始内容的请求
如果随后单击车辆列表的分页导航中的链接,则
- URL已更新以包含该页面。注意,它不是作为查询(
?
),而是作为片段(#
)的一部分,该片段从不发送到服务器,而是保留在客户端
- 请求页面的内容是通过POST请求(通过jQuery)获取的,然后该响应被合并到内容中,看起来像是通过链接获取的
如果您想模拟此POST请求,那么它会稍微复杂一些:
它包含一个nonce,您可以在您必须发送的初始内容(搜索ajax\u nonce
)中找到它(因此,获取初始内容,刮取nonce,然后将其与POST请求一起发送)
下面是一个带有CURL(替换nonce)的示例,该示例将把第2页的列表重新转换为JSON(即使响应标题说Content-Type:text/html;charset=UTF-8
curl -X POST https://www.pacificbmw.com/
-H "Content-Type: application/x-www-form-urlencoded"
-d "action=im_ajax_call&perform=get_results&page=2&_nonce=e085e144a19b3b493c7aab9aff479722&_post_id=6&_referer=/new-vehicles/"
这会回来的
{"results":"
<table class=\ "results_table\">\n
<tbody>\t\n\n
<tr class=\ "hidden-xs\">\n
<td colspan=\ "7\">\n
<!-- VEHICLE BLOCK -->\n
<div class=\ "vehicle list-view new
....
{“结果”:
\n
\t\n\n
\n
\n
\n
通过使用Watir和一个无头chrome浏览器,我能够刮取所需的数据,该浏览器允许在刮取页面之前运行ajax/javascript代码
require 'nokogiri'
require 'httparty'
require 'byebug'
require 'watir'
def scraper
url = "https://www.example.com/new-vehicles/"
unparsed_page = HTTParty.get(url)
parsed_page = Nokogiri::HTML(unparsed_page)
vehicles = Array.new
vehicle_listings = parsed_page.css("//div[@class='vehicle list-view new-vehicle publish']") #20 cars
page = 1
per_page = vehicle_listings.count #20
total = parsed_page.css('span.count').text.to_i #281
last_page = (total.to_f / per_page.to_f).ceil #14
# Create instance of headless chrome called browser
browser = Watir::Browser.new :chrome, headless: true
while page <= last_page
pagination_url = "https://www.example.com/new-vehicles/#action=im_ajax_call&perform=get_results&page=#{page}"
browser.goto(pagination_url)
pagination_unparsed_page = Nokogiri::HTML(browser.html)
puts pagination_url
puts "Page: #{page}"
puts ''
pagination_parsed_page = pagination_unparsed_page
pagination_vehicle_listings = pagination_parsed_page.css("//div[@class='vehicle list-view new-vehicle publish']") #20 cars
pagination_vehicle_listings.each do |vehicle_listing|
vehicle = {
stock_number: vehicle_listing.css('.stock-label')&.text.gsub("Stock #: ", '')
}
vehicles << vehicle
puts "Added #{vehicle[:stock_number]}"
puts ""
end
page += 1
end
# Be sure to close the browser
browser.close
byebug
end
scraper
需要“nokogiri”
需要“httparty”
需要“byebug”
需要“watir”
def刮刀
url=”https://www.example.com/new-vehicles/"
unparsed_page=HTTParty.get(url)
解析的页面=Nokogiri::HTML(未解析的页面)
车辆=阵列。新
vehicle_listings=parsed_page.css(“//div[@class='vehicle list view new vehicle publish'])20辆车
页码=1
每页=车辆列表.计数#20
总计=已解析的页面.css('span.count').text.to#i#281
最后一页=(总计.至页/每页.至页).ceil#14
#创建名为browser的无头chrome实例
browser=Watir::browser.new:chrome,headless:true
虽然我不认为有必要提供那么多的输出,但也许您可以将其清理一下?请参见:,重点放在单词minimal上。很高兴您提供了一个完整的/可验证的代码示例,但您真的需要显示所有这些信息来解释问题吗?external\u c的代码是什么颜色:vehicle_listing.css('span.detail content')…
与此有关?向我们展示12页的详细调试是否有助于解释它?换句话说,您可能已经用大约8行代码和不到5%的调试输出解释了这个问题。进一步回答下面的问题,我想说,这个网站非常难刮。您使用的上述方法将d对于大多数网站来说都很好。这里的问题是分页是通过jQuery/AJAX请求来完成的,而不是通过GET请求中的常规查询参数来完成的。@Pascal很抱歉我在问题中减少了过多的输出。