Последователно извличане на бисквитки и трохи от yahoo finance за изтегляне на исторически данни

Работя по проект, включващ изтегляне на исторически данни за цените на акциите от yahoo finance. Стъпка в този процес включва определяне на правилната бисквитка и трохи, които да се използват с url за изтегляне на данните. Кодът, който имам в момента, работи само понякога, т.е. данните за запасите се извличат без никакви проблеми и ще се провалят при привидно произволни итерации. В пълния проблем изтеглям данни за множество акции. Проблемът, с който се сблъсквам, е липса на последователност при извличането на данните. Сблъсквам се с проблем при данните, които се връщат

b'{\n"finance":{\n"error":{\n"code":"Unauthorized",\n"description":"Invalid cookie"\n}\n}\n}\n

Така че, аз вярвам, че проблемът се крие в набора за извличане на бисквитки.

За да тествам проблема, написах малък скрипт, който се опитва да изтегли данни за една и съща стока в продължение на 20 итерации. Когато изпълнявам това, обикновено ще имам около 18 итерации, които работят правилно, а другите няма да работят. Итерациите, в които това се случва, се променят всеки път, когато изпълня тестовия скрипт.

Ето тестовия код, който използвах досега:

import requests
import time
import re
for k in range(20):
    symbol='AMZN'
    url="https://finance.yahoo.com/quote/%s/?p=%s" % (symbol, symbol)
    r = requests.get(url, timeout=10)
    cookie = r.cookies
    lines = r.content.decode('latin-1').replace('\\', '')
    lines = lines.replace('}', '\n')
    lines = lines.split('\n')
    for l in lines:
        if re.findall(r'CrumbStore', l):
            crumb = l.split(':')[2].strip('"')
    start_date = int(int(time.time())-15*86400)
    end_date = int(time.time())
    url = "https://query1.finance.yahoo.com/v7/finance/download/%s?period1=%s&period2=%s&interval=1d&events=history&crumb=%s" % (symbol, start_date, end_date, crumb)
    response = requests.get(url, cookies=cookie, timeout=10)
    for block in response.iter_content(1024):
        print(block)
        print(k)

Очаквам това да връща данните за цената на акциите всеки път, подобно на:

b'Date,Open,High,Low,Close,Adj Close,Volume\n2019-06-06,1737.709961,1760.000000,1726.130005,1754.359985,1754.359985,3689300\n2019-06-07,1763.699951,1806.250000,1759.489990,1804.030029,1804.030029,4808200\n2019-06-10,1822.000000,1884.869995,1818.000000,1860.630005,1860.630005,5371000'

понякога обаче получавам грешката. Има ли по-надежден начин да се гарантира, че данните са изтеглени правилно? Знам, че мога да го осъществя и да го изтегля, но кодът е ненадежден.

Имайте предвид, че това е подобно на опит за достъп до данните с лоша бисквитка/трошка директно в браузър, например чрез url:

https://query1.finance.yahoo.com/v7/finance/download/AMZN?period1=1559367165&period2=1560663165&interval=1d&events=history&crumb=ODCkS0u002FOZyL

Благодаря ти за помощта.


person melo_gonzo    schedule 21.06.2019    source източник
comment
Аз имам подобен проблем. Всъщност се опитвах да разбера как да приложа бисквитката правилно към URL адреса. Уведомете ме, ако сте намерили стабилно решение за вашия въпрос.   -  person VISQL    schedule 06.02.2020


Отговори (2)


Проблемът не е свързан с вашия код. Той е от страната на Yahoo сървъра. Виждам, че проблемът е напълно случаен. Ако ударите невалидна бисквитка, вие непрекъснато получавате невалидни бисквитки. Предполагам, че цикълът не може да ви помогне да прескочите този проблем.

Може би можете да запазите работеща двойка бисквитка и трохи веднъж. И можете да заредите тази двойка, за да получите данни.

# Save cookie.
with open('cookie', 'wb') as f:
    pickle.dump(cookie, f)

Зареждането на бисквитката е:

# Load cookie.
with open('cookie', 'rb') as f:
    session.cookies.update(pickle.load(f))
person bozcani    schedule 20.02.2020
comment
Здравей @bozcani! Добре дошли в Stack Overflow. Моля, не поставяйте просто връзки към други страници. Въпреки че връзката всъщност може да съдържа отговора, винаги е най-добре да обясните подробно. Освен това отговорът може да стане невалиден, ако връзките спрат да работят. Благодаря! - person Ashkan; 20.02.2020
comment
Благодаря за обратната връзка @Ashkan! Току-що актуализирах публикацията си. - person bozcani; 21.02.2020

Срещнах точно този проблем, опитвайки се да изтегля исторически данни за списък с акции. Поправих го с помощта на метода на груба сила, повтаряйки 5 пъти всяка заявка, след което излизам от цикъла, ако заявката успее. Ако заявката работи, първите няколко върнати знака са „Дата, отворено“.

    String crumb = getCrumb(securityID); // get the crumb

    String yahooQuery = "?period1=" + fromDate + "&period2=" + toDate + 
    "&interval=1d&events=history&crumb=" + crumb;

    String requestURL = 
    "https://query1.finance.yahoo.com/v7/finance/download/" + securityID + 
    yahooQuery;

    PostRequest stockDetail = new PostRequest(requestURL);

    for (int tries = 0; tries < 5; tries++) {

        // Get history CSV file
        stockDetail.send();

        if (stockDetail.getContent().contains("Date,Open")) {
            break;
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
    }
person running_turtle    schedule 23.03.2020