使用Nokogiri或RestClient在url上使用哈希值

时间:2016-04-12 09:58:37

标签: ruby-on-rails ruby ruby-on-rails-4 nokogiri rest-client

我有一个网址:

http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das

在我的浏览器中,我可以从该网址获取数据,但如果我使用nokogiri

Nokogiri::HTML(open('http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das'))

我得到了

URI::InvalidURIError: bad URI(is not URI?): http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das
from /home/worka/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/uri/common.rb:176:in `split'

还有RestClient

RestClient.get 'http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das'

我得到了同样的错误。

3 个答案:

答案 0 :(得分:0)

首先对您的网址进行编码,然后使用它。

url = 'http://172.0.0:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das'
encoded_url = CGI::escape(url)
Nokogiri::HTML(open(encoded_url))

答案 1 :(得分:0)

在处理URI时,最好使用为它们设计的工具,例如随Ruby提供的URI。

URI不能

http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das

因为data组件无效。如果您要添加data,那么我会从:

开始
require 'uri'

uri = URI.parse('http://172.0.0.1:22230/test.action?sign=x6das')
query = URI.decode_www_form(uri.query).to_h # => {"sign"=>"x6das"}
data = {"foo" => "bar","joe" => "doe"}
uri.query = URI.encode_www_form(query.merge(data)) # => "sign=x6das&foo=bar&joe=doe"
uri.to_s # => "http://172.0.0.1:22230/test.action?sign=x6das&foo=bar&joe=doe"

使用{"foo":"bar","joe":"doe"}的初始示例是JSON序列化数据,通常不会在这样的URL中传递。如果您需要创建JSON,请从初始哈希开始:

require 'json'

data = {"foo" => "bar","joe" => "doe"}
data.to_json # => "{\"foo\":\"bar\",\"joe\":\"doe\"}"

to_json将散列序列化为一个字符串,然后可以将其编码到URI中:

data = {"foo" => "bar","joe" => "doe"}

uri = URI.parse('http://172.0.0.1:22230/test.action?sign=x6das')
query = URI.decode_www_form(uri.query).to_h # => {"sign"=>"x6das"}
uri.query = URI.encode_www_form(query.merge('data' => data.to_json)) # => "sign=x6das&data=%7B%22foo%22%3A%22bar%22%2C%22joe%22%3A%22doe%22%7D"

但是,再次发送编码的JSON作为URI中的查询参数并不常见或标准,因为没有JSON编码,数据有效负载会更小。

答案 2 :(得分:-1)

好的,我解决了我的问题

url = http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das
RestClient.get(URI.encode(url.strip))