如何刮取延迟加载的页面

Raj*_*ary 5 ruby nokogiri web-scraping

这是我用于解析网页的代码.我在rails console中做到了.但是我没有在我的rails控制台中获得任何输出.我想要抓取的网站是延迟加载

require 'nokogiri'
require 'open-uri'

page = 1
while true
  url =  "http://www.justdial.com/functions"+"/ajxsearch.php?national_search=0&act=pagination&city=Delhi+%2F+NCR&search=Pandits"+"&where=Delhi+Cantt&catid=1195&psearch=&prid=&page=#{page}"


  doc = Nokogiri::HTML(open(url))
  doc = Nokogiri::HTML(doc.at_css('#ajax').text)
  d = doc.css(".rslwrp")
  d.each do |t|
     puts t.css(".jrcw").text
     puts t.css("span.jcn").text
     puts t.css(".jaid").text
     puts t.css(".estd").text
    page+=1
  end
end
Run Code Online (Sandbox Code Playgroud)

Ale*_*ein 6

您在这里有 2 个选择:

  1. 将纯 HTTP 抓取切换到一些支持 javascript 评估的工具,例如 Capybara(选择适当的驱动程序)。这可能会很慢,因为您在后台运行无头浏览器,而且您必须设置一些超时或想出另一种方法来确保在开始任何抓取之前加载您感兴趣的文本块。

  2. 第二种选择是使用 Web Developer 控制台并弄清楚如何加载这些文本块(哪些 AJAX 调用、它们的参数等)并在您的抓取工具中实现它们。这是更高级的方法,但性能更高,因为您不会像在选项 1 中那样做任何额外的工作。

祝你今天过得愉快!

更新:

您上面的代码不起作用,因为响应是包装在 JSON 对象中的 HTML 代码,而您正在尝试将其解析为原始 HTML。它看起来像这样:

{
  "error": 0,
  "msg": "request successful",
  "paidDocIds": "some ids here",
  "itemStartIndex": 20,
  "lastPageNum": 50,
  "markup": 'LOTS AND LOTS AND LOTS OF MARKUP'
}
Run Code Online (Sandbox Code Playgroud)

您需要的是解包 JSON,然后解析为 HTML:

require 'json' 

json = JSON.parse(open(url).read) # make sure you check http errors here
html = json['markup'] # can this field be empty? check for the json['error'] field
doc = Nokogiri::HTML(html) # parse as you like
Run Code Online (Sandbox Code Playgroud)

我还建议您不要使用,open-uri因为如果您由于工作方式open-uri(阅读链接的文章了解详细信息)而使用动态 url,您的代码可能会变得容易受到攻击,并且使用良好且功能更强大的库,例如HTTPartyRestClient

更新 2:对我来说最小的工作脚本:

require 'json'
require 'open-uri'
require 'nokogiri'

url = 'http://www.justdial.com/functions/ajxsearch.php?national_search=0&act=pagination&city=Delhi+%2F+NCR&search=Pandits&where=Delhi+Cantt&catid=1195&psearch=&prid=&page=2'

json = JSON.parse(open(url).read) # make sure you check http errors here
html = json['markup'] # can this field be empty? check for the json['error'] field
doc = Nokogiri::HTML(html) # parse as you like
puts doc.at_css('#newphoto10').attr('title')
# => Dr Raaj Batra Lal Kitab Expert in East Patel Nagar, Delhi
Run Code Online (Sandbox Code Playgroud)