Não foi possível analisar um resultado exato de uma página da web usando solicitações

8

Eu criei um script em python para analisar dois campos de uma página da web - total revenuee é preocupante date. Os campos que eu busco são javascript criptografados. Eles estão disponíveis na fonte da página dentro da matriz json. O script a seguir pode analisar esses dois campos de acordo.

No entanto, o problema é que a data visível nessa página é diferente daquela disponível na origem da página.

Link da página da Web

A data em que a página web é como este

A data no código fonte da página é como este

Existe claramente uma variação de um dia.

Depois de visitar a página da Web, quando você clica nessa guia, Quarterlypode ver os resultados:

Eu tentei com:

import re
import json
import requests

url = 'https://finance.yahoo.com/quote/GTX/financials?p=GTX'

res = requests.get(url)
data = re.findall(r'root.App.main[^{]+(.*);',res.text)[0]
jsoncontent = json.loads(data)
container = jsoncontent['context']['dispatcher']['stores']['QuoteSummaryStore']['incomeStatementHistoryQuarterly']['incomeStatementHistory']
total_revenue = container[0]['totalRevenue']['raw']
concerning_date = container[0]['endDate']['fmt']
print(total_revenue,concerning_date)

Resultado que recebo (receita em milhões):

802000000 2019-06-30

Resultado que desejo obter:

802000000 2019-06-29

Quando tento com esse ticker AAPL, obtenho a data exata, portanto, subtrair ou adicionar um dia não é uma opção.

Como posso obter a data exata desse site ?

Btw, eu sei como obtê-los usando selênio, então eu só gostaria de manter requests.

MITHU
fonte
3
Se as datas terminarem no máximo em um dia, meu primeiro palpite seria que a diferença vem da conversão de fuso horário.
Janne Karila
1
Tentei ativar o vpn usando um local diferente para ver o resultado, mas a variação ainda está lá @Janne Karila.
MITHU 9/10/19
Acabei de experimentar o seu código e a saída da instrução print era a mesma da página (2019-6-30).
Jack Fleeting
Sim, você está certo @Jack Fleeting, mas outros tickers certamente variam. De fato, você pode obter resultados diferentes em outro momento. Neste ponto, parece que Janne Karila estava certo em seu primeiro palpite. Suponho que possa haver alguma maneira de consertar isso.
MITHU 12/12/19
Você poderia fornecer mais alguns símbolos de ações com as datas corretas e com as datas erradas?
vida é complexa

Respostas:

2

Conforme mencionado nos comentários, você precisa converter a data no fuso horário apropriado (EST), o que pode ser feito com datetime e dateutil.

Aqui está um exemplo de trabalho:

import re
import json
import requests
from datetime import datetime, timezone
from dateutil import tz

url = 'https://finance.yahoo.com/quote/GTX/financials?p=GTX'

res = requests.get(url)
data = re.findall(r'root.App.main[^{]+(.*);',res.text)[0]
jsoncontent = json.loads(data)
container = jsoncontent['context']['dispatcher']['stores']['QuoteSummaryStore']['incomeStatementHistoryQuarterly']['incomeStatementHistory']
total_revenue = container[0]['totalRevenue']['raw']

EST = tz.gettz('EST')
raw_date = datetime.fromtimestamp(container[0]['endDate']['raw'], tz=EST)
concerning_date = raw_date.date().strftime('%d-%m-%Y')
print(total_revenue, concerning_date)
Restabelecer Monica
fonte
Parece ser o resultado que eu esperava ter. Não posso formatar a data como em 06-29-2019vez de 2019-06-29 19:00:00-05:00? Obrigado.
MITHU 15/10/19
1
@MITHU Adicionei isso em uma atualização. Primeiro você precisa converter o objeto datetime em uma data usando .date(), então você precisa usá .strftime-lo para convertê-lo no formato desejado.
Reintegrar Monica
2
Se eu tentar com esse ticker NVDAque levará a esse link , acho que a diferença é ainda maior.
MITHU 15/10/19
@MITHU Strange. Isso significa que o TZ provavelmente não é o problema, já que NVIDIAtambém está no EST. Vou procurar uma solução, mas agora não tenho noção do por que isso está acontecendo.
Reintegrar Monica
2

A seção atualizada desta resposta descreve a causa raiz das diferenças de data.


RESPOSTA ORIGINAL


Alguns dos valores brutos em seu JSON são carimbos de data e hora do UNIX.

Referência do seu código com modificações:

concerning_date_fmt = container[0]['endDate']['fmt']
concerning_date_raw = container[0]['endDate']['raw']
print(f'{concerning_date} -- {concerning_date_raw}')
# output 
2019-07-28 -- 1564272000 

'endDate': {'fmt': '2019-07-28', 'bruto': 1564272000}

1564272000 é o número de segundos decorridos desde 01 de janeiro de 1970. Esta data foi o início da época do Unix e a hora está no Tempo Universal Coordenado (UTC). 1564272000 é o equivalente a: 28/07/2019 00:00 (UTC).

Você pode ocultar esses registros de data e hora em um formato padrão de data e hora usando funções Python internas

from datetime import datetime
unix_timestamp = int('1548547200')

converted_timestamp = datetime.utcfromtimestamp(unix_timestamp).strftime('%Y-%m-%dT%H:%M:%SZ')
print (converted_timestamp)
# output Coordinated Universal Time (or UTC)
2019-07-28T00:00:00Z

reformatted_timestamp = datetime.strptime(converted_timestamp, '%Y-%m-%dT%H:%M:%SZ').strftime('%d-%m-%Y')
print (reformatted_timestamp)
# output
28-07-2019

Isso ainda não resolve o problema original relacionado às datas JSON e às datas da coluna sendo diferentes às vezes. Mas aqui está minha hipótese atual relacionada às disparidades de data que estão ocorrendo.

  1. A data json (fmt e raw) que está sendo extraída do root.App.main está no Tempo Universal Coordenado (UTC). Isso fica claro devido ao carimbo de data e hora do UNIX em bruto .

  2. As datas exibidas nas colunas da tabela parecem estar no fuso horário da hora padrão do leste (EST). EST é atualmente UTC-4. O que significa que 2019-07-28 22:00 (22:00) EST seria 2019-07-29 02:00 (02:00) UTC. O servidor que hospeda o finance.yahoo.com parece estar nos Estados Unidos, com base nos resultados do traceroute . Esses valores também estão no arquivo json :

    • 'exchangeTimezoneName': 'America / New_York'
    • 'exchangeTimezoneShortName': 'EDT'
  3. Também existe a possibilidade de que algumas diferenças de data estejam vinculadas ao código React subjacente , usado pelo site. Esse problema é mais difícil de diagnosticar, porque o código não está visível.

No momento, acredito que a melhor solução seria usar o registro de data e hora do UNIX como referência de hora da verdade. Esta referência pode ser usada para substituir a data da coluna da tabela.

Definitivamente, existe algum tipo de conversão acontecendo entre o arquivo JSON e as colunas.

ARQUIVO NVIDIA JSON: 'endDate': {'raw': 1561766400, 'fmt': '2019-06-29'}

Coluna Receita Total Associada da NVIDIA: 30/06/2019

MAS a data da coluna Receita total deve ser 28/06/2019 (EDT), porque o registro de data e hora UNIX para 1561766400 é 29/06/2019 00:00 (UTC).

A disparidade com a DELL é maior que um registro de data e hora básico do UNIX e uma conversão de registro de data e hora do EDT.

ARQUIVO DELL JSON: {"bruto": 1564704000, "fmt": "2019-08-02"}

Coluna Receita Total Associada da DELL: 31/07/2019

Se convertermos o registro de data e hora do UNIX em um registro de data e hora de EDT, o resultado será 1/8/2019, mas esse não é o caso no exemplo da DELL, que é 31/07/2019. Algo na base de códigos do Yahoo deve estar causando essa diferença.

Estou começando a acreditar que o React pode ser o culpado com essas diferenças de datas, mas não posso ter certeza sem fazer mais pesquisas.

Se React for a causa raiz, a melhor opção seria usar os elementos de data dos dados JSON.


RESPOSTA ATUALIZADA 10-17-2019


Esse problema é muito interessante, porque parece que essas datas da coluna estão vinculadas ao final oficial do trimestre fiscal de uma empresa e não a um problema de conversação de data.

Aqui estão vários exemplos para

  • Apple Inc. (AAPL)
  • Atlassian Corporation Plc (EQUIPE)
  • Arrowhead Pharmaceuticals, Inc. (ARWR):

As datas das colunas são:

  • 30/06/2019
  • 31/03/2019
  • 31/12/2018
  • 30/09/2018

Essas datas correspondem a esses trimestres fiscais.

  • Trimestre 1 (Q1): 1º de janeiro a 31 de março.
  • Trimestre 2 (Q2): 1º de abril a 30 de junho.
  • 3º trimestre (terceiro trimestre): 1º de julho a 30 de setembro.
  • 4º trimestre (quarto trimestre): 1º de outubro a 31 de dezembro

Essas datas de término do trimestre fiscal podem variar bastante, como mostra o exemplo da DELL.

DELL (publicado na NASDAQ) Fim do trimestre fiscal: julho de 2019

Data da coluna do Yahoo Finance : 31/07/2019

Data do JSON: 2019-08-02

No site da empresa:

Quando o ano fiscal da Dell Technologies termina?

  • Nosso ano fiscal é o período de 52 ou 53 semanas que termina na sexta-feira mais próxima a 31 de janeiro. Nosso ano fiscal de 2020 terminará em 31 de janeiro de 2020. Para exercícios fiscais anteriores, veja a lista abaixo: Nosso ano fiscal de 2019 terminou em 1º de fevereiro, 2019 Nosso ano fiscal de 2018 terminou em 2 de fevereiro de 2018 Nosso ano fiscal de 2017 terminou em 3 de fevereiro de 2017 Nosso ano fiscal de 2016 terminou em 29 de janeiro de 2016 Nosso ano fiscal de 2015 terminou em 30 de janeiro de 2015 Nosso ano fiscal de 2014 terminou em 31 de janeiro de 2014 Nosso ano fiscal de 2013 terminou em 1º de fevereiro de 2013

trimestres fiscais da dell

NOTA: As datas 05-03-19 e 08-02-19.

Estes são dos dados trimestrais JSON da DELL:

  • {'raw': 1564704000, 'fmt': '2019-08-02'}
  • {'raw': 1556841600, 'fmt': '2019-05-03'}

Parece que essas datas da coluna estão vinculadas às datas de término do trimestre fiscal de uma empresa. Portanto, recomendo que você use a data JSON como elemento de referência principal ou a data da coluna correspondente.

PS: Existe algum tipo de vodu de data no Yahoo, porque eles parecem mover essas datas do trimestre da coluna com base em feriados, fins de semana e final de mês.

A vida é complexa
fonte
1

Em vez de obter o fmtde concerning_date, é melhor obter o carimbo de data e hora.

concerning_date = container[0]['endDate']['raw']

No exemplo acima, você obterá o resultado 1561852800que pode ser transferido para uma data com um determinado fuso horário. (Dica: use datetimee pytz). Esse registro de data e hora produzirá os seguintes resultados com base no fuso horário:

Date in Los Angeles*: 29/06/2019, 17:00:00
Date in Berlin* :30/06/2019, 02:00:00
Date in Beijing*: 30/06/2019, 07:00:00
Date in New York* :29/06/2019, 19:00:00
Mohammed Abuiriban
fonte