无法使用请求解析网页的确切结果

时间:2019-10-09 09:04:19

标签: python json python-3.x web-scraping python-requests

我已经用python创建了一个脚本来解析网页中的两个字段-total revenue,它涉及date。我关注的字段是javascript加密的。它们在json数组中的页面源中可用。以下脚本可以相应地解析这两个字段。

但是,问题在于该页面中的可见日期与页面源中可用的日期不同。

Webpage link

该网页中的日期类似于 this

页面源中的日期类似于 this

显然会有一天的变化。

在访问该 webpage 后,点击该标签 Quarterly 您可以在那里看到结果:

我尝试过:

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)

我得到的结果(以百万为单位的收入):

802000000 2019-06-30

我希望得到的结果:

802000000 2019-06-29

尝试使用此行情自动收录器AAPL时,我会得到确切的日期,因此不能选择跟踪或添加日期。

如何从该站点获取确切日期

顺便说一句,我知道如何使用硒来获得它们,所以我只想坚持使用requests

3 个答案:

答案 0 :(得分:2)

如评论中所述,您需要将日期转换为适当的时区(EST),可以使用datetime和dateutil来完成。

这是一个有效的示例:

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)

答案 1 :(得分:2)

此答案的更新部分概述了日期差异的根本原因。


原始答案


JSON中的某些原始值是UNIX时间戳。

修改后的代码引用:

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 是自1970年1月1日以来经过的秒数。此日期是Unix纪元的开始,时间以世界协调时间(UTC)为单位。 1564272000 等同于:07/28/2019 12:00 am(UTC)。

您可以使用内置的Python函数

将这些时间戳转换为标准的 datetime 格式。
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

这仍然不能解决您的原始问题,该问题与JSON日期和列日期有时不同有关。但是,这是我目前与发生日期差异有关的假设。

  1. root.App.main 中提取的 json 日期(fmt和raw)在世界标准时间(UTC)中。这很清楚,因为 raw 中的UNIX时间戳。

  2. 表列中显示的日期似乎在东部标准时间(EST)时区。 EST当前为UTC-4。这意味着美国东部时间2019-07-28 22:00(10pm)将是世界标准时间2019-07-29 02:00(2am)。根据 traceroute ,托管 finance.yahoo.com 的服务器位于美国 结果。这些值也位于 json 文件中:

    • 'exchangeTimezoneName':'America / New_York'
    • 'exchangeTimezoneShortName':'EDT'
  3. 还有一些日期差异可能链接到该网站使用的基础 React 代码。由于该代码不可见,因此很难诊断此问题。

这时,我相信最好的解决方案是使用UNIX时间戳作为您的真实时间参考。此引用可用于替换表格列的日期。

在JSON文件和列之间肯定存在某种类型的转换。

  

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

     

NVIDIA关联总收入列:2019/6/30

但“总收入”列日期应为6/28/2019(EDT),因为 1561766400 的UNIX时间戳为06/29/2019 12:00 am(UTC)。

DELL 的差异大于基本的UNIX时间戳和EDT时间戳转换。

  

Dell JSON FILE:{“ raw”:1564704000,“ fmt”:“ 2019-08-02”}

     

DELL关联总收入列:2019/7/31

如果将UNIX时间戳转换为EDT时间戳,结果将为8/1/2019,但在DELL示例中并非如此,即7/31/2019。 Yahoo代码库中的某些内容必须引起这种差异。

我开始相信反应可能是造成这些日期差异的罪魁祸首,但我无法确定是否需要做更多的研究。

如果React是根本原因,那么最好的选择就是使用JSON数据中的日期元素。


更新后的答案10-17-2019


这个问题非常有趣,因为这些列日期似乎与公司的财政季度末相关,而不是日期对话问题。

以下是

的几个示例
  • Apple Inc.(AAPL)
  • Atlassian Corporation Plc(TEAM)
  • Arrowhead Pharmaceuticals,Inc.(ARWR):

其列日期为:

  • 6/30/2019
  • 2019/3/31
  • 12/31/2018
  • 9/30/2018

这些日期与这些财政季度相匹配。

  • 第一季度(Q1):1月1日至3月31日。
  • 第二季度(Q2):4月1日至6月30日。
  • 第3季度(第3季度):7月1日至9月30日。
  • 第4季度(Q4):10月1日至12月31日

如本DELL示例所示,这些会计季度结束日期可能会有很大差异。

Dell (在纳斯达克发布) 财政季度末:2019年7月

雅虎财经 列日期:7/31/2019

JSON日期:2019-08-02

从公司的网站上

  

戴尔技术公司的会计年度何时结束?

  • 我们的会计年度为52周或53周,截至最近的1月31日星期五。我们的2020会计年度将在2020年1月31日结束。有关以前的会计年度,请参见以下列表:我们的2019会计年度于2019年2月1日我们的2018财年截止于2018年2月2日我们的2017财年截止于2017年2月3日我们的2016财年截止于2016年1月29日我们的2015财年截止于2015年1月30日我们的2014财年截止于2014年1月31日,我们的2013财年于2013年2月1日结束

dell's fiscal quarters

注意:日期为05-03-19和08-02-19。

这些来自DELL的JSON季度数据:

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

这些列日期似乎与公司的财政季度结束日期相关联。因此,我建议您使用JSON日期作为主要参考元素或相应的列日期。

P.S。雅虎发生某种日期伏都教,因为他们似乎根据假期,周末和月底移动这些栏季度日期。

答案 2 :(得分:1)

获取时间戳记比获取fmt的{​​{1}}更好。

concerning_date

在上面的示例中,您将获得结果concerning_date = container[0]['endDate']['raw'] ,可以将其转换为具有特定时区的日期。 (提示:使用1561852800datetime)。该时间戳将根据时区产生以下结果:

pytz