如何抓取公共画面的仪表板?

时间:2020-05-29 21:59:45

标签: python web-scraping tableau-api

每天,我需要对公共Tableau仪表板上可用的数据进行分类。在定义了感兴趣的参数(时间序列频率,时间序列间隔等)之后,仪表板允许您下载序列。

如果我可以使用Python或R自动将这些系列下载到数据库中,那么我的生活会相对容易一些。我已经尝试分析页面上的请求,但是我无法再进一步了。有什么办法可以自动化这个过程?

信息中心:https://tableau.ons.org.br/t/ONS_Publico/views/DemandaMxima/HistricoDemandaMxima?:embed=y&:showAppBanner=false&:showShareOptions=true&:display_count=no&:showVizHome=no

1 个答案:

答案 0 :(得分:4)

此答案类似于this one,但初始URL页和tableau基本URL不同。流程/算法基本上保持不变,但我将详细说明步骤:

图形是根据API的结果在JS中生成的:

POST https://tableau.ons.org.br/ROOT_PATH/bootstrapSession/sessions/SESSION_ID

SESSION_ID参数(除其他外)位于用于构建iframe的URL的tsConfigContainer文本区域中。

https://tableau.ons.org.br/t/ONS_Publico/views/DemandaMxima/HistricoDemandaMxima?:embed=y&:showAppBanner=false&:showShareOptions=true&:display_count=no&:showVizHome=no开始:

  • 有一个ID为tsConfigContainer的文本区域,带有一堆json值
  • 提取session_id和根路径(vizql_root
  • https://tableau.ons.org.br/ROOT_PATH/bootstrapSession/sessions/SESSION_ID作为表单数据在sheetId上进行POST
  • 从结果中提取json(结果不是json)

代码:

import requests
from bs4 import BeautifulSoup
import json
import re

url = "https://tableau.ons.org.br/t/ONS_Publico/views/DemandaMxima/HistricoDemandaMxima"

r = requests.get(
    url,
    params= {
        ":embed":"y",
        ":showAppBanner":"false",
        ":showShareOptions":"true",
        ":display_count":"no",
        "showVizHome": "no"
    }
)
soup = BeautifulSoup(r.text, "html.parser")

tableauData = json.loads(soup.find("textarea",{"id": "tsConfigContainer"}).text)

dataUrl = f'https://tableau.ons.org.br{tableauData["vizql_root"]}/bootstrapSession/sessions/{tableauData["sessionid"]}'

r = requests.post(dataUrl, data= {
    "sheet_id": tableauData["sheetId"],
})

dataReg = re.search('\d+;({.*})\d+;({.*})', r.text, re.MULTILINE)
info = json.loads(dataReg.group(1))
data = json.loads(dataReg.group(2))

print(data["secondaryInfo"]["presModelMap"]["dataDictionary"]["presModelHolder"]["genDataDictionaryPresModel"]["dataSegments"]["0"]["dataColumns"])