2015-06-11 1 views
0

У меня возникают проблемы с получением данных от GitHub Archive.Проблемы с кодировкой URL-адресов с фигурными фигурными скобками

Основная проблема заключается в моей проблеме с кодировкой {} и .. в моем URL-адресе. Возможно, я неправильно читаю API Github или неправильно понимаю кодировку.

require 'open-uri' 
require 'faraday' 

conn = Faraday.new(:url => 'http://data.githubarchive.org/') do |faraday| 
    faraday.request :url_encoded    # form-encode POST params 
    faraday.response :logger     # log requests to STDOUT 
    faraday.adapter Faraday.default_adapter # make requests with Net::HTTP 
end 

#query = '2015-01-01-15.json.gz' #this one works!! 
query = '2015-01-01-{0..23}.json.gz' #this one doesn't work 
encoded_query = URI.encode(query) 

response = conn.get(encoded_query) 
p response.body 
+0

Что 'encoded_query' выглядеть после запуска? Вы получаете сообщения об ошибках в 'response'? –

+0

Получение этой ошибки «NoSuchKey Указанный ключ не существует« –

+0

И как выглядит 'encoded_query'? –

ответ

1

Пример GitHub Архив для извлечения диапазона файлов:

wget http://data.githubarchive.org/2015-01-01-{0..23}.json.gz 

{0..23} часть интерпретируется самим Wget в диапазоне от 0 .. 23. Вы можете проверить это, выполнив что команда с -v флагом, который возвращает:

wget -v http://data.githubarchive.org/2015-01-01-{0..1}.json.gz 
--2015-06-11 13:31:07-- http://data.githubarchive.org/2015-01-01-0.json.gz 
Resolving data.githubarchive.org... 74.125.25.128, 2607:f8b0:400e:c03::80 
Connecting to data.githubarchive.org|74.125.25.128|:80... connected. 
HTTP request sent, awaiting response... 200 OK 
Length: 2615399 (2.5M) [application/x-gzip] 
Saving to: '2015-01-01-0.json.gz' 

2015-01-01-0.json.gz          100%[===========================================================================================================================================>] 2.49M 3.03MB/s in 0.8s 

2015-06-11 13:31:09 (3.03 MB/s) - '2015-01-01-0.json.gz' saved [2615399/2615399] 

--2015-06-11 13:31:09-- http://data.githubarchive.org/2015-01-01-1.json.gz 
Reusing existing connection to data.githubarchive.org:80. 
HTTP request sent, awaiting response... 200 OK 
Length: 2535599 (2.4M) [application/x-gzip] 
Saving to: '2015-01-01-1.json.gz' 

2015-01-01-1.json.gz          100%[===========================================================================================================================================>] 2.42M 867KB/s in 2.9s 

2015-06-11 13:31:11 (867 KB/s) - '2015-01-01-1.json.gz' saved [2535599/2535599] 

FINISHED --2015-06-11 13:31:11-- 
Total wall clock time: 4.3s 
Downloaded: 2 files, 4.9M in 3.7s (1.33 MB/s) 

другими словами, Wget будет подставляя значения в URL, а затем получить этот новый URL. Это не очевидное поведение, и это хорошо документировано, но вы можете найти упоминание об этом «там». Например, в «All the Wget Commands You Should Know»:

7. Download a list of sequentially numbered files from a server 
wget http://example.com/images/{1..20}.jpg 

Чтобы сделать то, что вы хотите, вы должны перебрать диапазон в Ruby, используя что-то вроде этого непроверенного кода:

0.upto(23) do |i| 
    response = conn.get("/2015-01-01-#{ i }.json.gz") 
    p response.body 
end 
+0

Просто избили меня до удара :) – seane

1

Чтобы получить лучшее представление о том, что идет не так, давайте начнем с примером, приведенным в документации GitHub:

wget http://data.githubarchive.org/2015-01-01-{0..23}.json.gz 

вещь, чтобы отметить здесь, что {0..23} является автомагический получением экс подкрепленный башем. Вы можете увидеть это, выполнив следующую команду:

echo {0..23} 
> 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 

Это означает, что wget не дозвонились только один раз, но вместо этого будет вызван в общей сложности 24 раз. Проблема, с которой вы сталкиваетесь, заключается в том, что Ruby не автоматически расширяет {0..23}, как и bash, и вместо этого вы делаете буквальный вызов http://data.githubarchive.org/2015-01-01-{0..23}.json.gz, которого не существует.

Вместо этого вам нужно будет перебрать 0..23 себя и сделать единственный вызов каждый раз, когда:

(0..23).each do |n| 
    query = "2015-01-01-#{n}.json.gz" 
    encoded_query = URI.encode(query) 
    response = conn.get(encoded_query) 
    p response.body 
end 
+0

ic..thanks. это многое объясняет. –