无法从 Morningstar 抓取 dataid - 如何从 Python 访问网络检查工具?

Posted

技术标签:

【中文标题】无法从 Morningstar 抓取 dataid - 如何从 Python 访问网络检查工具?【英文标题】:Cannot scrape dataid from Morningstar - How can I access the Network inspection tool from Python? 【发布时间】:2019-05-27 10:42:13 【问题描述】:

我正在尝试爬取 Morningstar.com 以获取网站上可用的每个基金的财务数据和价格。幸运的是,我在抓取财务数据(持股、资产配置、投资组合、风险等)方面没有问题,但是当找到以 JSON 格式为每个基金提供每日价格的 URL 时,有一个“dataid”值这在 html 代码中不可用,没有它就无法知道承载所有价格的确切 URL。

我尝试将整个页面打印为许多基金的文本,但它们都没有在 HTML 代码中显示我获取价格所需的“dataid”值。托管价格的 URL 还包括“secid”,它很容易被抓取,但与我需要抓取的“dataid”完全没有关系。

import requests
from lxml import html
import re
import json

quote_page = "https://www.morningstar.com/etfs/arcx/aadr/quote.html"
prices1 = "https://mschart.morningstar.com/chartweb/defaultChart?type=getcc&secids="
prices2 = "&dataid="
prices3 = "&startdate="
prices4 = "&enddate="
starting_date = "2018-01-01"
ending_date = "2018-12-28"

quote_html = requests.get(quote_page, timeout=10)
quote_tree = html.fromstring(quote_html.text)
security_id = re.findall('''meta name=['"]secId['"]\s*content=['"](.*?)['"]''', quote_html.text)[0]
security_type = re.findall('''meta name=['"]securityType['"]\s*content=['"](.*?)['"]''', quote_html.text)[0]

data_id = "8225"

daily_prices_url = prices1 + security_id + ";" + security_type + prices2 + data_id + prices3 + starting_date + prices4 + ending_date
daily_prices_html = requests.get(daily_prices_url, timeout=10)
json_prices = daily_prices_html.json()
for json_price in json_prices["data"]["r"]:
    j_prices = json_price["t"]
    for j_price in j_prices:
        daily_prices = j_price["d"]
        for daily_price in daily_prices:
            print(daily_price["i"] + " || " + daily_price["v"])

上面的代码只适用于“AADR”ETF,因为我在“data_id”变量中手动复制并粘贴了“dataid”值,如果没有这条信息,就无法访​​问每日价格。我不想使用 Selenium 作为查找“dataid”的替代方法,因为它是一个非常慢的工具,我的目的是为超过 28k 的资金抓取数据,所以我只尝试了机器人网络抓取方法。 您对如何访问网络检查工具有任何建议,这是迄今为止我发现的唯一显示“dataid”的来源? 提前致谢

【问题讨论】:

【参考方案1】:

数据 id 可能没那么重要。我更改了与 AADR 关联的代码 F00000412E,同时保持数据 ID 不变。

我从这里得到了所有这些代码的列表:

https://www.firstrade.com/scripts/free_etfs/io.php

然后将选择的代码添加到您的网址中,例如

[
    "AIA",
    "iShares Asia 50 ETF",
    "FOUSA06MPQ"
  ]

使用FOUSA06MPQ

https://mschart.morningstar.com/chartweb/defaultChart?type=getcc&secids=FOUSA06MPQ;FE&dataid=8225&startdate=2017-01-01&enddate=2018-12-30

您可以通过将其他基金作为基准添加到您的图表来验证这些值,例如XNAS:AIA

12 月 28 日的值为 55.32。将其与检索到的 JSON 进行比较:

我重复了这个

[
    "ALD",
    "WisdomTree Asia Local Debt ETF",
    "F00000M8TW"
  ]

https://mschart.morningstar.com/chartweb/defaultChart?type=getcc&secids=F00000M8TW;FE&dataid=8225&startdate=2017-01-01&enddate=2018-12-30

【讨论】:

感谢 QHarr,不幸的是,有些 ETF 具有不同的 dataid 值(ACT = 8226、ALD = 8217、BOND = 8217 等),我只是无法弄清楚这些值与什么相关。我只能在网络部分使用 GoogleChrome 上的检查工具手动查看以 JSON 格式存储每日价格的 URL,这为我提供了价格图表的来源。有没有办法在 Python 中访问检查工具的网络部分? 我似乎仍然得到正确的结果,保持 id 不变。以 ARCX:ALD 为例 感谢 QHarr,我尝试将所有基金的 dataid 设置为 8225,看看是否无法通过这种方式检索某些基金的价格。非常感谢您的帮助 使用 ETF 的“8825”和共同基金的“8217”作为“data_id”,大约 95% 的基金价格已被正确抓取。对于其余的,我手动检查了正确的“data_id”,问题现在解决了。再次感谢 QHarr【参考方案2】:

dataId 8217 对我来说效果很好,无论安全性如何。

【讨论】:

以上是关于无法从 Morningstar 抓取 dataid - 如何从 Python 访问网络检查工具?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中抓取具有可点击内容的网站

python Quantopian Morningstar行业代码

Morningstar收购“直接指数化”公司-再次证明投资者对被动投资创新的认可

js iframe跨域访问

无法从网页中抓取产品标题

使用 Jsoup 获取网页元素