Как я могу БЫСТРО получить строку из одной из первых нескольких строк длинного CSV-файла по удаленному URL-адресу?

Я работаю над заданием, где я получаю несколько цен на акции из Интернета, используя систему цен на акции Yahoo. К сожалению, API Yahoo, который я должен использовать, возвращает файл .csv файл, который, по-видимому, содержит строку для каждого дня торговли акциями, что составляет не менее 5 тысяч строк для акций, с которыми я работаю, и более 10 тысяч строк для некоторых из них (пример).

Меня интересует только текущая цена, которая находится во второй строке.

Я сейчас делаю это:

require 'open-uri'
def get_ticker_price(stock)
   open("http://ichart.finance.yahoo.com/table.csv?s=#{stock}") do |io|
      io.read.split(',')[10].to_f
   end
end

…но это очень медленно.

  1. Вся задержка происходит из-за получения файла или из-за того, как я с ним справляюсь? io.read читает весь файл?

  2. Есть ли способ загрузить только первые пару строк из CSV-файла Yahoo?

  3. Если ответы на вопросы 1 и 2 не делают этот вопрос неактуальным, есть ли лучший способ его обработки, который не требует просмотра всего файла (при условии, что это то, что делает io.read)?


person Oblivious Sage    schedule 16.07.2012    source источник
comment
Звучит подозрительно так: stackoverflow.com/questions/1120350/   -  person Jerdak    schedule 16.07.2012
comment
То, как работает команда open, заключается в том, чтобы сначала сохранить загруженную веб-страницу во временный файл, а затем передать этот объект ввода-вывода Tempfile в данный блок. Т.е. open("http://...") { |io| puts File.read(io.path) } выводит содержимое загруженной веб-страницы. Таким образом, метод open загружает весь файл еще до того, как он попадет в ваш блок. К сожалению, я не знаю, как частично загрузить файл (раньше в этом не было необходимости), поэтому я не могу ответить на 2 или 3, однако я почти уверен, что вы не сможете использовать open для этого.   -  person David Miani    schedule 16.07.2012
comment
Вы можете уменьшить размер файла, указав дату последней сделки в строке запроса, если используете сервис котировок. пример: finance.yahoo.com/d/quotes.csv?s= MO&f=snd1l1yr Если вы можете использовать этот другой сервис, дополнительная информация здесь: greenido.wordpress.com/2009/12/22/yahoo-finance-hidden-api   -  person Tim    schedule 16.07.2012
comment
на самом деле, я нашел лучшую ссылку на сервис, который вы используете. Вот пример получения данных только за сегодня: ichart.finance.yahoo.com/   -  person Tim    schedule 16.07.2012


Ответы (1)


Вы можете использовать параметры строки запроса, чтобы сократить данные до текущей даты, используя параметры диапазона дат.

пример для MO 13.07.2012: (начало/конец месяца начинается с нулевого индекса, {00 - 11}).

http://ichart.finance.yahoo.com/table.csv?s=MO&a=06&b=13&c=2012&d=6&e=13&f=2012&g=d

описание API здесь: http://etraderzone.com/free-scripts/47-historical-quotes-yahoo.html

person Tim    schedule 16.07.2012
comment
Спасибо, Тим! Это решило мою проблему, но я собираюсь отложить принятие этого на день или два, чтобы посмотреть, сможет ли кто-нибудь еще придумать способ Ruby сделать это, так как это было технически вопросом спросил. :) - person Oblivious Sage; 16.07.2012
comment
Первый комментарий к вашему вопросу ссылается на другой вопрос SO, где на него дан ответ. - person Lars Haugseth; 16.07.2012
comment
@LarsHaugseth: Оба ответа на этот вопрос влекут за собой манипулирование сокетами низкого уровня, что, как указал автор одного из ответов, на самом деле не очень Ruby-способ решения проблемы. Поскольку этому вопросу 3 года, я подумал, что, возможно, стоит немного подождать, чтобы увидеть, есть ли сейчас более чистое решение (несколько версий Ruby позже). - person Oblivious Sage; 16.07.2012
comment
Похоже, что сервер, на котором работает служба, не поддерживает заголовок HTTP-запроса Range, поэтому вам, вероятно, не повезло сделать это с чистыми библиотеками HTTP. - person Lars Haugseth; 17.07.2012