我想用Nokogiri遍历一些HTML文档。 获取XML对象后,我想让Nokogiri使用的最后一个URL获取文档作为我的JSON响应的一部分。
def url = "http://ow.ly/hh8ri"
doc = Nokogiri::HTML(open(url)
...
Nokogiri在内部将其重定向到http://www.mp.rs.gov.br/imprensa/noticias/id30979.html,但我希望能够访问它。
我想知道“doc”对象是否可以访问某些URL作为属性或其他内容。 有人知道解决方法吗?
顺便说一句,我想要完整的URL,因为我正在遍历HTML以找到<img>
标签,而有些则有相关的标签,如:“/ media/image/image.png”,然后我调整了一些使用:
URI.join(url, relative_link_url).to_s
图片网址应为:
http://www.mp.rs.gov.br/media/imprensa/2013/01/30979_260_260__trytr.jpg
而不是:
http://ow.ly/hh8ri/media/imprensa/2013/01/30979_260_260__trytr.jpg
编辑:IDEA
class Scraper < Nokogiri::HTML::Document
attr_accessor :url
class << self
def new(url)
html = open(url, ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE)
self.parse(html).tap do |d|
url = URI.parse(url)
response = Net::HTTP.new(url.host, url.port)
head = response.start do |r|
r.head url.path
end
d.url = head['location']
end
end
end
end
答案 0 :(得分:3)
使用Mechanize。 URL将始终转换为绝对值:
require 'mechanize'
agent = Mechanize.new
page = agent.get 'http://ow.ly/hh8ri'
page.images.map{|i| i.url.to_s}
#=> ["http://www.mp.rs.gov.br/images/imprensa/barra_area.gif", "http://www.mp.rs.gov.br/media/imprensa/2013/01/30979_260_260__trytr.jpg"]
答案 1 :(得分:2)
因为您的示例使用的是OpenURI,这是要求的代码,而不是Nokogiri。 Nokogiri不知道内容的来源。
OpenURI可以轻松告诉您:
require 'open-uri'
starting_url = 'http://www.example.com'
final_uri = nil
puts "Starting URL: #{ starting_url }"
io = open(starting_url) { |io| final_uri = io.base_uri }
doc = io.read
puts "Final URL: #{ final_uri.to_s }"
哪个输出:
Starting URL: http://www.example.com
Final URL: http://www.iana.org/domains/example
base_uri
记录在OpenURI::Meta模块中。
答案 2 :(得分:1)
我最近遇到了完全相同的问题。我所做的是创建一个继承自Nokogiri::HTML::Document
的类,然后重写new
类方法来解析文档,然后将url保存在一个带有访问器的实例变量中:
require 'nokogiri'
require 'open-uri'
class Webpage < Nokogiri::HTML::Document
attr_accessor :url
class << self
def new(url)
html = open(url)
self.parse(html).tap do |d|
d.url = url
end
end
end
end
然后你可以创建一个新的Webpage
,它可以访问Nokogiri::HTML::Document
所有常规方法:
w = Webpage.new("http://www.google.com")
w.url
#=> "http://www.google.com"
w.at_css('title')
#=> [#<Nokogiri::XML::Element:0x4952f78 name="title" children=[#<Nokogiri::XML::Text:0x4952cb2 "Google">]>]
如果你有一个从图像标签获得的相对网址,你可以通过将url
访问者的返回值传递给URI.join
来使其绝对:
relative_link_url = "/media/image/image.png"
=> "/media/image/image.png"
URI.join(w.url, relative_link_url).to_s
=> "http://www.google.com/media/image/image.png"
希望有所帮助。
P.S。这个问题的标题很容易引起误解。 “访问Nokogiri HTML文档的URL”更加清晰。