打开URI - 无效的URI错误,编码/转义不影响

时间:2014-10-15 19:32:18

标签: ruby http character-encoding yahoo-finance open-uri

我正在构建一个YahooFinance Api,并在尝试使用开放URI时不断碰壁。

代码:

uri = ("http://ichart.finance.yahoo.com/table.csv?s=#{URI.escape(code)}&a=#{start_month}&b=#{start_day}&c=#{start_year}&d=#{end_month}&e=#{end_day}&f=#{end_year}&g=d&ignore=.csv")
    puts "#{uri}"
    conn = open(uri)

错误:

`split': bad URI(is not URI?): http://ichart.finance.yahoo.com/table.csv?s=%255EIXIC&a=00&b=1&c=1994&d=09&e=14&f=2014&g=d&ignore=.csv} (URI::InvalidURIError)

我已尝试URI.unescape(code)code输出为^IXIC,并保留任何URI方法,code将以{{1}的形式出现}}

在阅读了堆栈溢出后,我尝试了这两种方法都无济于事:

%5EIXIC

uri = URI.parse(URI.encode(url.strip))

即使在查看了另一个ruby yahoo-finance gem的代码here之后,我似乎无法找到解决方案。任何帮助是极大的赞赏。感谢

编辑:当我用单引号手动输入网址时,我可以使用safeurl = URI.encode(url.strip)。做双引号(用于插入红宝石对象),在这里发挥作用吗?

3 个答案:

答案 0 :(得分:2)

请勿尝试将变量注入网址。如果它们包含需要根据规范进行编码的字符,则不会通过插值进行编码。相反,利用适合工作的工具,如Ruby的URI类或Addressable :: URI gem。

参见" How to post a URL containting curly braces and colons"如何使用经过良好测试的车轮做到这一点。

在你的情况下,这样的事情会起作用:

require 'uri'

code = 'qwer3456*&^%'
start_month = 1
start_day = 1
start_year = 2014
end_month = 12
end_day = 31
end_year = 2015

uri = URI.parse("http://ichart.finance.yahoo.com/table.csv")
uri.query = URI.encode_www_form(
  {
    'g' => 'd',
    'ignore' => '.csv',
    's' => code,
    'a' => start_month,
    'b' => start_day,
    'c' => start_year,
    'd' => end_month,
    'e' => end_day,
    'f' => end_year
  }
)
uri.to_s # => "http://ichart.finance.yahoo.com/table.csv?g=d&ignore=.csv&s=qwer3456*%26%5E%25&a=1&b=1&c=2014&d=12&e=31&f=2015"

答案 1 :(得分:1)

虽然我不认为API端点是正确的,但代码对我有用:

[1] pry(main)> uri = URI("http://ichart.finance.yahoo.com/table.csv?s=%255EIXIC&a=00&b=1&c=1994&d=09&e=14&f=2014&g=d&ignore=.csv")
=> #<URI::HTTP:0x007fd63a2fff40 URL:http://ichart.finance.yahoo.com/table.csv?s=%255EIXIC&a=00&b=1&c=1994&d=09&e=14&f=2014&g=d&ignore=.csv>
[3] pry(main)> Net::HTTP.get(uri)
=> "<!doctype html public \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html><head><title>Yahoo! - 404 Not Found</title><style>\n/* nn4 hide */ \n/*/*/\nbody {font:small/1.2em arial,helvetica,clean,sans-serif;font:x-small;text-align:center;}table {font-size:inherit;font:x-small;}\nhtml>body {font:83%/1.2em arial,helvetica,clean,sans-serif;}input {font-size:100%;vertical-align:middle;}p, form {margin:0;padding:0;}\np {padding-bottom:6px;margin-bottom:10px;}#doc {width:48.5em;margin:0 auto;border:1px solid #fff;text-align:center;}#ygma {text-align:right;margin-bottom:53px}\n#ygma img {float:left;}#ygma div {border-bottom:1px solid #ccc;padding-bottom:8px;margin-left:152px;}#bd {clear:both;text-align:left;width:75%;margin:0 auto 20px;}\nh1 {font-size:135%;text-align:center;margin:0 0 15px;}legend {display:none;}fieldset {border:0 solid #fff;padding:.8em 0 .8em 4.5em;}\nform {position:relative;background:#eee;margin-bottom:15px;border:1px solid #ccc;border-width:1px 0;}\n#s1p {width:15em;margin-right:.1em;}\nform span {position:absolute;left:70%;top:.8em;}form a {font:78%/1.2em arial;display:block;padding-left:.8em;white-space:nowrap;background: url(http://l.yimg.com/a/i/s/bullet.gif) no-repeat left center;} \nform .sep {display:none;}.more {text-align:center;}#ft {padding-top:10px;border-top:1px solid #999;}#ft p {text-align:center;font:78% arial;}\n/* end nn4 hide */\n</style></head>\n<body><div id=\"doc\">\n<div id=\"ygma\"><a href=\"http://us.rd.yahoo.com/404/*http://www.yahoo.com\"><img\nsrc=http://l.yimg.com/a/i/yahoo.gif\nwidth=147 height=31 border=0 alt=\"Yahoo!\"></a><div><a\nhref=\"http://us.rd.yahoo.com/404/*http://www.yahoo.com\">Yahoo!</a>\n - <a href=\"http://us.rd.yahoo.com/404/*http://help.yahoo.com\">Help</a></div></div>\n<div id=\"bd\"><h1>Sorry, the page you requested was not found.</h1>\n<p>Please check the URL for proper spelling and capitalization. If\nyou're having trouble locating a destination on Yahoo!, try visiting the\n<strong><a\nhref=\"http://us.rd.yahoo.com/404/*http://www.yahoo.com\">Yahoo! home\npage</a></strong> or look through a list of <strong><a\nhref=\"http://us.rd.yahoo.com/404/*http://docs.yahoo.com/docs/family/more/\">Yahoo!'s\nonline services</a></strong>. Also, you may find what you're looking for\nif you try searching below.</p>\n<form name=\"s1\" action=\"http://us.rd.yahoo.com/404/*-http://search.yahoo.com/search\"><fieldset>\n<legend><label for=\"s1p\">Search the Web</label></legend>\n<input type=\"text\" size=30 name=\"p\" id=\"s1p\" title=\"enter search terms here\">\n<input type=\"submit\" value=\"Search\">\n<span><a href=\"http://us.rd.yahoo.com/404/*http://search.yahoo.com/search/options?p=\">advanced search</a> <span class=sep>|</span> <a href=\"http://us.rd.yahoo.com/404/*http://buzz.yahoo.com\">most popular</a></span>\n</fieldset></form>\n<p class=\"more\">Please try <strong><a\nhref=\"http://us.rd.yahoo.com/404/*http://help.yahoo.com\">Yahoo!\nHelp Central</a></strong> if you need more assistance.</p>\n</div><div id=\"ft\"><p>Copyright &copy; 2014 Yahoo! Inc.\nAll rights reserved. <a\nhref=\"http://us.rd.yahoo.com/404/*http://privacy.yahoo.com\">Privacy\nPolicy</a> - <a\nhref=\"http://us.rd.yahoo.com/404/*http://docs.yahoo.com/info/terms/\">Terms\nof Service</a></p></div>\n</div></body></html>\n"

答案 2 :(得分:0)

看起来您的问题是ignore=.csv部分。

我的意思是这可能是尝试将其编码为域扩展。可能你应该删除点来解决问题。