No se puede analizar un resultado exacto de una página web mediante solicitudes


8

He creado un script en Python para analizar dos campos de una página web, total revenuey es preocupante date. Los campos que busco están encriptados con JavaScript. Están disponibles en la fuente de la página dentro de json array. El siguiente script puede analizar esos dos campos en consecuencia.

Sin embargo, el problema es que la fecha visible en esa página es diferente de la disponible en la fuente de la página.

Enlace a la página web

La fecha en que la página web es como esta

La fecha en la fuente de la página es como esta

Claramente hay una variación de un día.

Después de visitar esa página web cuando hace clic en esta pestaña Quarterly, puede ver los resultados allí:

He intentado con:

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 obtengo (ingresos en millones):

802000000 2019-06-30

Resultado que deseo obtener:

802000000 2019-06-29

Cuando trato con este ticker AAPL, obtengo la fecha exacta, por lo que no es una opción restar o agregar un día.

¿Cómo puedo obtener la fecha exacta de ese sitio ?

Por cierto, sé cómo usarlos con selenio, así que solo me gustaría seguir requests.


3
Si las fechas están apagadas como máximo un día, mi primera suposición sería que la diferencia proviene de la conversión de zona horaria.
Janne Karila

1
Intenté activar vpn usando una ubicación diferente para ver el resultado, pero la variación sigue ahí @Janne Karila.
MITHU

Acabo de probar su código y el resultado de la declaración de impresión fue el mismo que en la página (2019-6-30).
Jack huyendo el

Sí, sí, eres @Jack Fleeting, pero seguramente otros tickers varían. De hecho, puede obtener resultados diferentes en otro momento. En este punto, parece que Janne Karila tenía razón en su primera suposición. Supongo que podría haber alguna forma de arreglar eso.
MITHU

¿Podría proporcionar más símbolos de acciones con las fechas correctas y las que tienen las fechas incorrectas?
vida es compleja el

Respuestas:


2

Como se menciona en los comentarios, debe convertir la fecha a la zona horaria apropiada (EST), que se puede hacer con datetime y dateutil.

Aquí hay un ejemplo de trabajo:

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)

Parece ser el resultado que esperaba tener. ¿No puedo formatear la fecha como en 06-29-2019lugar de 2019-06-29 19:00:00-05:00? Gracias.
MITHU

1
@MITHU Agregué esto en una actualización. Primero debe convertir el objeto de fecha y hora en una fecha usando .date(), luego debe usar .strftimepara convertirlo al formato deseado.
Restablece a Monica el

2
Si trato con este ticker NVDAque me llevará a este enlace , encuentro que la diferencia es aún mayor.
MITHU

@MITHU Extraño. Eso significa que TZ probablemente no sea el problema, ya NVIDIAque también está en EST. Buscaré una solución, pero ahora no tengo idea de por qué sucede esto.
Vuelva a instalar a Monica el

2

La sección actualizada de esta respuesta describe la causa raíz de las diferencias de fechas.


RESPUESTA ORIGINAL


Algunos de los valores sin formato en su JSON son marcas de tiempo UNIX.

Referencia de su código con modificaciones:

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', 'raw': 1564272000}

1564272000 es el número de segundos transcurridos desde el 1 de enero de 1970. Esta fecha fue el inicio de la época de Unix y la hora está en hora universal coordinada (UTC). 1564272000 es el equivalente a: 28/07/2019 12:00 am (UTC).

Puede convertir estas marcas de tiempo a un formato de fecha y hora estándar utilizando las funciones integradas de Python

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

Esto todavía no resuelve su problema original relacionado con las fechas JSON y las fechas de columna que a veces son diferentes. Pero aquí está mi hipótesis actual relacionada con las disparidades de fechas que están ocurriendo.

  1. La fecha json (fmt y raw) que se extraen de root.App.main están en Tiempo Universal Coordinado (UTC). Esto está claro debido a la marca de tiempo de UNIX en bruto .

  2. Las fechas que se muestran en las columnas de la tabla parecen estar en la zona horaria de la hora estándar del este (EST). EST es actualmente UTC-4. Lo que significa que 2019-07-28 22:00 (10pm) EST sería 2019-07-29 02:00 (2am) UTC. El servidor que aloja finance.yahoo.com parece estar en los Estados Unidos, según los resultados de traceroute . Estos valores también están en el archivo json :

    • 'exchangeTimezoneName': 'América / Nueva_York'
    • 'exchangeTimezoneShortName': 'EDT'
  3. También existe la posibilidad de que algunas de las diferencias de fecha estén vinculadas con el código React subyacente , que utiliza el sitio. Este problema es más difícil de diagnosticar porque el código no es visible.

En este momento, creo que la mejor solución sería utilizar la marca de tiempo UNIX como referencia de tiempo de verdad. Esta referencia podría usarse para reemplazar la fecha de la columna de la tabla.

Definitivamente, hay algún tipo de conversión entre el archivo JSON y las columnas.

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

Columna de ingresos totales asociados de NVIDIA: 30/06/2019

PERO la fecha de la columna de Ingresos totales debe ser 28/06/2019 (EDT), porque la marca de tiempo UNIX para 1561766400 es 29/06/2019 12:00 am (UTC).

La disparidad con DELL es mayor que una marca de tiempo UNIX básica y una conversión de marca de tiempo EDT.

ARCHIVO DELL JSON: {"raw": 1564704000, "fmt": "2019-08-02"}

Columna de ingresos totales asociados de DELL: 31/07/2019

Si convertimos la marca de tiempo UNIX en una marca de tiempo EDT, el resultado sería 8/1/2019, pero ese no es el caso en el ejemplo de DELL, que es 31/07/2019. Algo dentro de la base del código de Yahoo tiene que estar causando esta diferencia.

Estoy empezando a creer que React podría ser el culpable de estas diferencias de fechas, pero no puedo estar seguro sin investigar más.

Si React es la causa raíz, entonces la mejor opción sería utilizar los elementos de fecha de los datos JSON.


RESPUESTA ACTUALIZADA 10-17-2019


Este problema es muy interesante, porque parece que las fechas de estas columnas están vinculadas al final oficial del trimestre fiscal de una empresa y no a un problema de conversación de fecha.

Aquí hay varios ejemplos para

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

Sus fechas de columna son:

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

Estas fechas coinciden con estos trimestres fiscales.

  • Trimestre 1 (Q1): 1 de enero - 31 de marzo.
  • Trimestre 2 (Q2): 1 de abril - 30 de junio.
  • Trimestre 3 (Q3): 1 de julio - 30 de septiembre.
  • Trimestre 4 (Q4): 1 de octubre - 31 de diciembre

Estas fechas de finalización del trimestre fiscal pueden variar mucho, como lo muestra este ejemplo de DELL.

DELL (publicado en NASDAQ) Fin del trimestre fiscal: julio de 2019

Fecha de la columna de Yahoo Finance : 31/07/2019

Fecha JSON: 2019-08-02

Desde el sitio web de la compañía:

¿Cuándo termina el año fiscal de Dell Technologies?

  • Nuestro año fiscal es el período de 52 o 53 semanas que finaliza el viernes más cercano al 31 de enero. Nuestro año fiscal 2020 finalizará el 31 de enero de 2020. Para los años fiscales anteriores, consulte la lista a continuación: Nuestro año fiscal 2019 terminó el 1 de febrero, 2019 Nuestro año fiscal 2018 terminó el 2 de febrero de 2018 Nuestro año fiscal 2017 terminó el 3 de febrero de 2017 Nuestro año fiscal 2016 terminó el 29 de enero de 2016 Nuestro año fiscal 2015 terminó el 30 de enero de 2015 Nuestro año fiscal 2014 terminó el 31 de enero de 2017, 2014 Nuestro año fiscal 2013 finalizó el 1 de febrero de 2013

trimestres fiscales de dell

NOTA: Las fechas 05-03-19 y 08-02-19.

Estos son de los datos del trimestre JSON para DELL:

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

Parece que estas fechas de columna están vinculadas a las fechas de finalización del trimestre fiscal de una empresa. Por lo tanto, recomendaría que use la fecha JSON como elemento de referencia principal o la fecha de columna correspondiente.

PD: Hay algún tipo de vudú de fechas en Yahoo, porque parecen mover estas fechas de trimestre de columna en función de días festivos, fines de semana y fines de mes.


1

En lugar de obtener el fmtde concerning_date, es mejor obtener la marca de tiempo.

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

En el ejemplo anterior, obtendrá el resultado 1561852800que puede transferir a una fecha con una determinada zona horaria. (Sugerencia: uso datetimey pytz). Esta marca de tiempo arrojará los siguientes resultados según la zona horaria:

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.