在JavaScript更改值之前和之后使用Nokogiri和Ruby进行抓取

在JavaScript更改值之前和之后使用Nokogiri和Ruby进行抓取,javascript,ruby,web-scraping,nokogiri,Javascript,Ruby,Web Scraping,Nokogiri,我有一个程序,从中获取价值 我目前的代码是: doc = Nokogiri::HTML(open(source_url)) puts doc.css('span.indexDate').text date = doc.css('span.indexDate').text date = Date.parse(date) puts date values = doc.css('table#CdsIndexTable td.col2 span') puts values 这将正确地从“CDS索引”

我有一个程序,从中获取价值

我目前的代码是:

doc = Nokogiri::HTML(open(source_url))

puts doc.css('span.indexDate').text
date = doc.css('span.indexDate').text
date = Date.parse(date)
puts date
values = doc.css('table#CdsIndexTable td.col2 span')
puts values
这将正确地从“CDS索引”表中刮取第二列的日期和值,这很好。现在,我想从我面临问题的“债券指数”表中刮取类似的值

我可以看到JavaScript函数在不加载页面和不更改页面URL的情况下对其进行更改。这两个表之间的区别在于它们的ID不同,这正是它们应该有的。但不幸的是,当我尝试:

values = doc.css('table#BondIndexTable')
puts values
我从债券指数表中什么也得不到。但如果我使用以下方法,我会从CDS索引表中获取值:

values = doc.css('table#CdsIndexTable')
puts values

如何从这两个表中获取值?

是一个带有JavaScript API的无头浏览器。由于您需要在正在抓取的页面上运行脚本,浏览器将为您执行此操作;PhantomJS将允许您在脚本执行后操作和刮取页面。

如果您不想使用PhantomJS,也可以使用Firefox或Chrome开发工具上的网络嗅探器,您将看到HTML表数据随javascript POST请求返回到服务器

然后,您不必使用Nokogiri打开原始页面URL,而是从Ruby脚本运行本文,并解析和解释该数据。看起来它只是嵌入了HTML的JSON数据。您可以提取HTML并将其提供给Nokogiri

这需要一些额外的检测工作,但我已经在JavaScript网页和抓取中多次使用这种方法。对于大多数简单的任务,它都可以工作,但需要深入了解页面和网络流量的内部工作原理

下面是来自Javascript POST请求的JSON数据示例:

债券:

CD:

这是一个快速而肮脏的解决方案,只是为了让你有一个想法。这将从初始页面获取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%"]

您可以使用水豚和Poltergeist驱动程序来执行Javascript并格式化页面。Poltergeist是PhantomJS无头浏览器的包装器。下面是一个如何做到这一点的示例:

require 'rubygems'
require 'capybara'
require 'capybara/dsl'
require 'capybara/poltergeist'

Capybara.default_driver = :poltergeist
Capybara.run_server = false

module GetPrice
  class WebScraper
    include Capybara::DSL

    def get_page_data(url)
      visit(url)
      doc = Nokogiri::HTML(page.html)
      doc.css('td.col2 span')
    end
  end
end

scraper = GetPrice::WebScraper.new
puts scraper.get_page_data('https://web.apps.markit.com/WMXAXLP?YYY2220_zJkhPN/sWPxwhzYw8K4DcqW07HfIQykbYMaXf8fTzWT6WKnuivTcM0W584u1QRwj').map(&:text).inspect
有关使用Amazon.com的完整示例,请访问此处:

Nokogiri是否执行javascript?如果是这样,并且那些“javascript函数”使用ajax,那么跨域策略是否会阻止它们完成?你试过像PhantomJS这样的东西吗?Nokogiri不运行JavaScript。@K.M.RakibulIslam Ok。看起来不太简单。您可能需要请求头中嵌入的原始网页中的cookie。这超出了一个简单答案的范围,所以也许你想试试PhantomJS。我使用Chrome开发者工具中的网络面板获得了链接:。只需按下live网页上的链接,观察javascript使用开发工具进行的网络调用。可以简化这一过程,因为它可以为您处理cookie,还可以让您访问解析的Nokogiri文档。