如果您不想使用 PhantomJS,您也可以在 Firefox 或 Chrome 开发工具上使用网络嗅探器,您将看到 HTML 表数据通过 javascript POST 请求返回到服务器。
然后,您无需使用 Nokogiri 打开原始页面 URL,而是从您的 Ruby 脚本运行此 POST 并解析和解释该数据。看起来它只是嵌入了 HTML 的 JSON 数据。您可以提取 HTML 并将其提供给 Nokogiri。
它需要一些额外的侦探工作,但我已经多次使用这种方法处理 JavaScript 网页和抓取。它适用于大多数简单的任务,但需要深入研究页面和网络流量的内部工作原理。
下面是来自 Javascript POST 请求的 JSON 数据示例:
债券:
https ://web.apps.markit.com/AppsApi/GetIndexData?indexOrBond=bond&ClientCode=WSJ
CDS:
https ://web.apps.markit.com/AppsApi/GetIndexData?indexOrBond=cds&ClientCode=WSJ
这是快速而肮脏的解决方案,只是为了让您有所了解。这将从初始页面获取 cookie 并在请求中使用它来获取 JSON 数据,然后解析 JSON 数据并将提取的 HTML 提供给 Nokogiri:
require 'rubygems'
require 'nokogiri'
require 'open-uri'
require 'json'
# Open the initial page to grab the cookie from it
p1 = open('https://web.apps.markit.com/WMXAXLP?YYY2220_zJkhPN/sWPxwhzYw8K4DcqW07HfIQykbYMaXf8fTzWT6WKnuivTcM0W584u1QRwj')
# Save the cookie
cookie = p1.meta['set-cookie'].split('; ',2)[0]
# Open the JSON data page using our cookie we just obtained
p2 = open('https://web.apps.markit.com/AppsApi/GetIndexData?indexOrBond=bond&ClientCode=WSJ',
'Cookie' => cookie)
# Get the raw JSON
json = p2.read
# Parse it
data = JSON.parse(json)
# Feed the html portion to Nokogiri
doc = Nokogiri.parse(data['html'])
# Extract the values
values = doc.css('td.col2 span')
puts values.map(&:text).inspect
=> ["0.02%", "0.02%", "n.a.", "-0.03%", "0.02%", "0.04%",
"0.01%", "0.02%", "0.08%", "-0.01%", "0.03%", "0.01%", "0.05%", "0.04%"]