如何抓取具有延迟加载的页面
How to scrape pages which have lazy loading
这是我用于解析网络的代码 page.I 在 rails 中完成 console.But 我在 rails [=15] 中没有得到任何输出=] 我想抓取的网站正在延迟加载
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
这里有 2 个选项:
将纯 HTTP 抓取切换到一些支持 javascript 评估的工具,例如 Capybara(选择 proper driver)。这可能会很慢,因为您是 运行 引擎盖下的无头浏览器,而且您必须设置一些超时或想出另一种方法来确保在开始任何操作之前加载您感兴趣的文本块刮.
第二种选择是使用 Web Developer 控制台并弄清楚这些文本块是如何加载的(AJAX 调用、它们的参数等)并在您的抓取工具中实现它们。这是更高级的方法,但性能更高,因为您不会做任何额外的工作,就像您在选项 1 中所做的那样。
祝你有愉快的一天!
更新:
您上面的代码不起作用,因为响应是 HTML 代码包装在 JSON 对象中,而您正试图将其解析为原始 HTML。它看起来像这样:
{
"error": 0,
"msg": "request successful",
"paidDocIds": "some ids here",
"itemStartIndex": 20,
"lastPageNum": 50,
"markup": 'LOTS AND LOTS AND LOTS OF MARKUP'
}
您需要解包 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
我也会advise you against using open-uri
since your code may become vulnerable if you use dynamic urls because of the way open-uri
works (read the linked article for the details) and use good and more feature-wise libraries such as HTTParty and RestClient。
更新 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
这是我用于解析网络的代码 page.I 在 rails 中完成 console.But 我在 rails [=15] 中没有得到任何输出=] 我想抓取的网站正在延迟加载
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
这里有 2 个选项:
将纯 HTTP 抓取切换到一些支持 javascript 评估的工具,例如 Capybara(选择 proper driver)。这可能会很慢,因为您是 运行 引擎盖下的无头浏览器,而且您必须设置一些超时或想出另一种方法来确保在开始任何操作之前加载您感兴趣的文本块刮.
第二种选择是使用 Web Developer 控制台并弄清楚这些文本块是如何加载的(AJAX 调用、它们的参数等)并在您的抓取工具中实现它们。这是更高级的方法,但性能更高,因为您不会做任何额外的工作,就像您在选项 1 中所做的那样。
祝你有愉快的一天!
更新:
您上面的代码不起作用,因为响应是 HTML 代码包装在 JSON 对象中,而您正试图将其解析为原始 HTML。它看起来像这样:
{
"error": 0,
"msg": "request successful",
"paidDocIds": "some ids here",
"itemStartIndex": 20,
"lastPageNum": 50,
"markup": 'LOTS AND LOTS AND LOTS OF MARKUP'
}
您需要解包 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
我也会advise you against using open-uri
since your code may become vulnerable if you use dynamic urls because of the way open-uri
works (read the linked article for the details) and use good and more feature-wise libraries such as HTTParty and RestClient。
更新 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