User Agent / Обходной файл cookie для очистки веб-страниц в MATLAB - PullRequest
0 голосов
/ 12 июня 2018

Я несколько дней пытался (используя другие ответы на этом сайте и MathWorks ), чтобы обойти crumb, которые Yahoo Finance добавляет в конце ссылкичтобы загрузить файл CSV, например, для CSV с данными Nasdaq100 в браузере Chrome, вы получите ссылку: https://query1.finance.yahoo.com/v7/finance/download/%5ENDX?period1=496969200&period2=1519513200&interval=1d&events=history&crumb=dnhBC8SRS9G (нажав на кнопку «Загрузить данные» на этой странице Yahoo Finance).

Очевидно, что crumb=dnhBC8SRS9G изменяется в зависимости от файлов cookie и агента пользователя, поэтому я попытался настроить MATLAB соответствующим образом, чтобы замаскировать себя под браузер Chrome (копирование файла cookie / агента пользователя, найденного в Chrome):

useragent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36';

cookie ='PRF=t%3D%255ENDX; expires=Thu, 11-Jun-2020 09:06:31 GMT; path=/; domain=.finance.yahoo.com';

opts = weboptions('UserAgent',useragent,'KeyName','WWW_Authenticate','KeyValue','dnhBC8SRS9G','KeyName','Cookie','KeyValue',cookie)

url = 'https://query1.finance.yahoo.com/v7/finance/download/^NDX?period1=496969200&period2=1519513200&interval=1d&events=history&crumb=dnhBC8SRS9G' ;

response = webread(url,opts)

Но независимо от того, что я делаю (используя webread или дополнительную функцию urlread2), я получаю ответ, что я "не авторизован".Приведенный выше код MATLAB дает мне ответ:

Error using readContentFromWebService (line 45)
The server returned the status 401 with message "Unauthorized" in response to the request to URL
https://query1.finance.yahoo.com/v7/finance/download/%5ENDX?period1=496969200&period2=1519513200&interval=1d&events=history&crumb=dnhBC8SRS9G.

Error in webread (line 122)
[varargout{1:nargout}] = readContentFromWebService(connection, options);

Error in TEST2 (line 22)
response = webread(url,opts)

Любая помощь будет принята с благодарностью, я просто хочу заставить работать основы, даже если это означает, что мне нужно вручную скопировать crumb из Chrome-браузер в MATLAB перед первым запросом.(Я видел, что они решили это в Python, C # и т. Д., И я следовал этим решениям в максимально возможной степени, так что это должно быть выполнимо и в MATLAB, верно?)

РЕДАКТИРОВАТЬ: Если это поможетКогда я запускаю urlread2 вместо webread в конце моего кода, то есть:

[output,extras] = urlread2(url,'GET');
extras.firstHeaders

Я получаю следующий вывод из MATLAB:

ans = 

  struct with fields:

                   Response: 'HTTP/1.1 401 Unauthorized'
     X_Content_Type_Options: 'nosniff'
           WWW_Authenticate: 'crumb'
               Content_Type: 'application/json;charset=utf-8'
             Content_Length: '136'
                       Date: 'Tue, 12 Jun 2018 13:07:38 GMT'
                        Age: '0'
                        Via: 'http/1.1 media-router-omega4.prod.media.ir2.yahoo.com (ApacheTrafficServer [cMsSf ]), http/1.1 media-ncache-api17.prod.media.ir2.yahoo.com (ApacheTrafficServer [cMsSf ]), http/1.1 media-ncache-api15.prod.media.ir2.yahoo.com (ApacheTrafficServer [cMsSf ]), http/1.1 media-router-api12.prod.media.ir2.yahoo.com (ApacheTrafficServer [cMsSf ]), https/1.1 e3.ycpi.seb.yahoo.com (ApacheTrafficServer [cMsSf ])'
                     Server: 'ATS'
                    Expires: '-1'
              Cache_Control: 'max-age=0, private'
  Strict_Transport_Security: 'max-age=15552000'
                 Connection: 'keep-alive'
                  Expect_CT: 'max-age=31536000, report-uri="http://csp.yahoo.com/beacon/csp?src=yahoocom-expect-ct-report-only"'
Public_Key_Pins_Report_Only: 'max-age=2592000; pin-sha256="2fRAUXyxl4A1/XHrKNBmc8bTkzA7y4FB/GLJuNAzCqY="; pin-sha256="2oALgLKofTmeZvoZ1y/fSZg7R9jPMix8eVA6DH4o/q8="; pin-sha256="Gtk3r1evlBrs0hG3fm3VoM19daHexDWP//OCmeeMr5M="; pin-sha256="I/Lt/z7ekCWanjD0Cvj5EqXls2lOaThEA0H2Bg4BT/o="; pin-sha256="JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg="; pin-sha256="SVqWumuteCQHvVIaALrOZXuzVVVeS7f4FGxxu6V+es4="; pin-sha256="UZJDjsNp1+4M5x9cbbdflB779y5YRBcV6Z6rBMLIrO4="; pin-sha256="Wd8xe/qfTwq3ylFNd3IpaqLHZbh2ZNCLluVzmeNkcpw="; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="cAajgxHlj7GTSEIzIYIQxmEloOSoJq7VOaxWHfv72QM="; pin-sha256="dolnbtzEBnELx/9lOEQ22e6OZO/QNb6VSSX2XHA3E7A="; pin-sha256="i7WTqTvh0OioIruIfFR4kMPnBqrS2rdiVPl/s2uC/CY="; pin-sha256="iduNzFNKpwYZ3se/XV+hXcbUonlLw09QPa6AYUwpu4M="; pin-sha256="lnsM2T/O9/J84sJFdnrpsFp3awZJ+ZZbYpCWhGloaHI="; pin-sha256="r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E="; pin-sha256="uUwZgwDOxcBXrQcntwu+kYFpkiVkOaezL0WYEZ3anJc="; includeSubdomains; report-uri="http://csp.yahoo.com/beacon/csp?src=yahoocom-hpkp-report-only"'

И мой weboptions вывод:

opts = 

  weboptions with properties:

  CharacterEncoding: 'auto'
          UserAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'
            Timeout: 5
           Username: ''
           Password: ''
            KeyName: ''
           KeyValue: ''
        ContentType: 'auto'
      ContentReader: []
          MediaType: 'application/x-www-form-urlencoded'
      RequestMethod: 'auto'
        ArrayFormat: 'csv'
       HeaderFields: {'Cookie'  'PRF=t%3D%255ENDX; expires=Thu, 11-Jun-2020 09:06:31 GMT; path=/; domain=.finance.yahoo.com'}
CertificateFilename: '/opt/matlab/r2017a/sys/certificates/ca/rootcerts.pem'

Ответы [ 3 ]

0 голосов
/ 14 июня 2018

Ниже приведен скрипт, который загружает данные за последний месяц для акций AAPL и создает файл .csv с именем AAPL_14-05-2018_14-06-2018 , который содержит дату, открытие, максимум, минимум, close, adj close и информация о томе, как найдено здесь .

%Choose any ticker.
ticker = 'AAPL'; %'FB','AMZN'...

%Base url.
url = 'https://query1.finance.yahoo.com/v8/finance/chart/GOOG?symbol=';
%weboption constructor.
opts = weboptions();

%Start retrieving data from today.
today = datetime('now');
today.TimeZone = 'America/New_York';

%Convert dates to unix timestamp.
todayp = posixtime(today);
%Last week.
weekp  = posixtime(datetime(addtodate(datenum(today),-7,'day'),'ConvertFrom','datenum'));
%Last month.
monthp = posixtime(datetime(addtodate(datenum(today),-1,'month'),'ConvertFrom','datenum'));
%Last year.
yearp = posixtime(datetime(addtodate(datenum(today),-1,'year'),'ConvertFrom','datenum'));

%Add ticker.
url = strcat(url,ticker);

%Construct url, add time intervals. The following url is for last month worth of data.
url = strcat(url,'&period1=',num2str(monthp,'%.10g'),'&period2=',num2str(todayp,'%.10g'),'&interval=','1d');

%Execute HTTP request.
data = webread(url,opts);

%Get data.
dates    = flipud(datetime(data.chart.result.timestamp,'ConvertFrom','posixtime'));
high     = flipud(data.chart.result.indicators.quote.high);
low      = flipud(data.chart.result.indicators.quote.low);
vol      = flipud(data.chart.result.indicators.quote.volume);
open     = flipud(data.chart.result.indicators.quote.open);
close    = flipud(data.chart.result.indicators.quote.close);
adjclose = flipud(data.chart.result.indicators.adjclose.adjclose);

%Create table.
t = table(dates,open,high,low,close,adjclose,vol);

%Format filename: ticker, start date, end date.
namefile = strcat(ticker,'_',char(datetime(monthp,'Format','dd-MM-yyyy','ConvertFrom','posixtime')),...
           '_',char(datetime(todayp,'Format','dd-MM-yyyy','ConvertFrom','posixtime')),'.csv');

%Write table to file.
writetable(t,namefile);

Вывод файла .csv (отображается только последние несколько дней):

     dates               open         high        low       close     adjclose    vol
14/06/2018 16:46    191.5500031 191.5700073 190.2200012 190.7599945 190.7599945 10252639
13/06/2018 13:30    192.4199982 192.8800049 190.4400024 190.6999969 190.6999969 21431900
12/06/2018 13:30    191.3899994 192.6100006 191.1499939 192.2799988 192.2799988 16911100
11/06/2018 13:30    191.3500061 191.9700012 190.2100067 191.2299957 191.2299957 18308500
08/06/2018 13:30    191.1699982 192         189.7700043 191.6999969 191.6999969 26656800
07/06/2018 13:30    194.1399994 194.1999969 192.3399963 193.4600067 193.4600067 21347200
06/06/2018 13:30    193.6300049 194.0800018 191.9199982 193.9799957 193.9799957 20933600
05/06/2018 13:30    193.0700073 193.9400024 192.3600006 193.3099976 193.3099976 21566000

вышеЯ получаю данные за последний месяц.В комментариях я показываю, как это можно адаптировать и за последнюю неделю, и за последний год.Я могу легко адаптировать код и преобразовать его в функцию, которую вы можете использовать для любого запаса и временного интервала.Вам просто нужно сказать мне, какие временные интервалы вас интересуют.

0 голосов
/ 29 июля 2018

Yahoo имеет ряд проверок, чтобы убедиться, что запрос поступает от веб-браузера.Проверьте эту функцию https://www.mathworks.com/matlabcentral/fileexchange/68361-yahoo-finance-data-downloader, которая заставляет Yahoo Finance полагать, что запрос поступает из браузера.

Вот несколько примеров того, как эта функция может использоваться для загрузки и анализа рыночных данных.https://github.com/Lenskiy/market-data-functions

0 голосов
/ 13 июня 2018

Хорошо, поэкспериментировал с Curl, и кажется, что то, что вы пытаетесь сделать, невозможно по указанному URL.Стоит отметить, что крошка и cookie часто меняются, поэтому мне приходилось анализировать ответы двух запросов GET каждый раз, когда я запускал скрипт, чтобы получить их значения.

Я проведу тебя через мою попытку.

  1. GET запросить и сохранить файл cookie.
  2. Разобрать файл cookie для cookie.
  3. Распечатать файл cookie в файл.
  4. GET запросить и сохранить html.
  5. Разбор HTML и получение крошки.
  6. URL-адрес формы.
  7. Запрос скручивания формы.
  8. Выполнение запроса.

Код:

%Get cookie.
command = 'curl -s --cookie-jar cookie.txt https://finance.yahoo.com/quote/GOOG?p=GOOG';
%Execute request.
system(command);
%Read file.
cookie_file = fileread('cookie.txt');
%regexp the cookie.
cookie = regexp(cookie_file,'B\s*(.*)','tokens');
cookie = cell2mat(cookie{1});

%Print cookie to file (for curl purposes only).
file = fopen('mycookie.txt','w');
fprintf(file,'%s',cookie);

%Get request.
command = 'curl https://finance.yahoo.com/quote/GOOG?p=GOOG > goog.txt';
%Execute request.
system(command);
%Read file.
crumb_file = fileread('goog.txt');
%regexp the crumb.
crumb = regexp(crumb_file,'(?<="CrumbStore":{"crumb":")(.*)(?="},"UserStore":)','tokens');
crumb = crumb{:};

%Form the URL.
url = 'https://query1.finance.yahoo.com/v7/finance/download/AAPL?period1=1492524105&period2=1495116105&interval=1d&events=history&crumb=';
url = strcat(url,crumb);

%Form the curl command.
command = strcat('curl',{' '},'-v -L -b',{' '},'mycookie.txt',{' '},'-H',{' '},'"User-Agent:',{' '},'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36','"',{' '},'"',url,'"');
command = command{1};
system(command);

Последний запрос скручивания:

curl -v -L -b mycookie.txt -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36" "https://query1.finance.yahoo.com/v7/finance/download/^NDX?period1=496969200&period2=1519513200&interval=1d&events=history&crumb=dSpwQstrQDp"

В последнем запросе скручивания я использую следующие флаги:

-v: verbosity
-L: follow redirects
-b: use cookie file
-H: user agent header field (tried spoofing it with my browser)

И для каждогопопытка, ответ будет следующим:

 {
    "finance": {
        "error": {
            "code": "Unauthorized",
            "description": "Invalid cookie"
        }
    }
}

Я изучил ответ сервера, и каждое значение заголовка успешно отправляется клиентом, однако оно всегда приводит к одной и той же ошибке.Теперь я подозреваю, что вы просто больше не можете этого делать, как объяснено здесь .Таким образом, как указал пользователь, вам, возможно, потребуется выполнить очистку веб-страниц из другого места.Возможно, если вы найдете рабочий URL, вы можете открыть новый вопрос, и я был бы рад помочь.

...