【问题标题】:How can I extract values from Tableau on this webpage如何在此网页上从 Tableau 中提取值
【发布时间】:2020-08-01 04:05:29
【问题描述】:

我正在尝试从此网页中提取每个州和县的“流动性指数”值: https://www.cuebiq.com/visitation-insights-mobility-index/

首选输出是所有可用地点和日期的地点(州/县)面板数据。

还有另一个帖子 (How can I scrape tooltips value from a Tableau graph embedded in a webpage) 有类似的问题。我尝试在那里遵循解决方案,但它似乎不适用于我的情况。

非常感谢。

(我尝试过的一种方法是下载从 Tableau 生成的 PDF 文件,其中包含特定日期的所有县的值。但是,我仍然需要找到一种方法来为数据中的每个日期提出请求。无论如何,如果您有比这条路线更好的主意,请告诉我。

【问题讨论】:

    标签: python web-scraping web-crawler tableau-api


    【解决方案1】:

    此画面数据 url 不返回任何数据。事实上,它只渲染值的图像(可能是画布),我猜它会根据坐标检测点击。可能是为了缓存值并快速渲染而采用这种方式。

    但是当您点击一个州时,它实际上会返回数据,但似乎并不总是返回该州的结果(但适用于各个县)。

    我找到的解决方案是使用工具提示来获取状态数据。当您单击状态时,它会生成如下请求:

    POST https://public.tableau.com/{path}/{session_id}/commands/tabsrv/render-tooltip-server
    

    使用以下表单参数:

    worksheet: US Map - State - CMI
    dashboard: CMI
    tupleIds: [18]
    vizRegionRect: {"r":"viz","x":496,"y":148,"w":0,"h":0,"fieldVector":null}
    allowHoverActions: false
    allowPromptText: true
    allowWork: false
    useInlineImages: true
    

    其中tupleIds: [18] 指的是状态列表中的状态索引,按字母倒序排列,如下所示:

    stateNames = ["Wyoming","Wisconsin","West Virginia","Washington","Virginia","Vermont","Utah","Texas","Tennessee","South Dakota","South Carolina","Rhode Island","Pennsylvania","Oregon","Oklahoma","Ohio","North Dakota","North Carolina","New York","New Mexico","New Jersey","New Hampshire","Nevada","Nebraska","Montana","Missouri","Mississippi","Minnesota","Michigan","Massachusetts","Maryland","Maine","Louisiana","Kentucky","Kansas","Iowa","Indiana","Illinois","Idaho","Georgia","Florida","District of Columbia","Delaware","Connecticut","Colorado","California","Arkansas","Arizona","Alabama"]
    

    它提供了一个带有工具提示 html 的 json,其中包含您要提取的 CMI 和 YoY 值:

    {
        "vqlCmdResponse": {
            "cmdResultList": [{
                "commandName": "tabsrv:render-tooltip-server",
                "commandReturn": {
                    "tooltipText": "{\"htmlTooltip\": \"<HTML HERE WITH THE VALUES>\"}]},\"overlayAnchors\":[]}"
                }
            }]
        }
    }
    

    唯一需要注意的是,您必须为每个状态发出一个请求:

    import requests
    from bs4 import BeautifulSoup
    import json
    import time
    
    data_host = "https://public.tableau.com"
    
    r = requests.get(
        f"{data_host}/views/CMI-2_0/CMI",
        params= {
            ":showVizHome":"no",
        }
    )
    soup = BeautifulSoup(r.text, "html.parser")
    
    tableauData = json.loads(soup.find("textarea",{"id": "tsConfigContainer"}).text)
    
    dataUrl = f'{data_host}{tableauData["vizql_root"]}/bootstrapSession/sessions/{tableauData["sessionid"]}'
    
    r = requests.post(dataUrl, data= {
        "sheet_id": tableauData["sheetId"],
    })
    data = []
    
    stateNames = ["Wyoming","Wisconsin","West Virginia","Washington","Virginia","Vermont","Utah","Texas","Tennessee","South Dakota","South Carolina","Rhode Island","Pennsylvania","Oregon","Oklahoma","Ohio","North Dakota","North Carolina","New York","New Mexico","New Jersey","New Hampshire","Nevada","Nebraska","Montana","Missouri","Mississippi","Minnesota","Michigan","Massachusetts","Maryland","Maine","Louisiana","Kentucky","Kansas","Iowa","Indiana","Illinois","Idaho","Georgia","Florida","District of Columbia","Delaware","Connecticut","Colorado","California","Arkansas","Arizona","Alabama"]
    
    for stateIndex, state in enumerate(stateNames):
        time.sleep(0.5) #for throttling
        r = requests.post(f'{data_host}{tableauData["vizql_root"]}/sessions/{tableauData["sessionid"]}/commands/tabsrv/render-tooltip-server',
            data = {
            "worksheet": "US Map - State - CMI",
            "dashboard": "CMI",
            "tupleIds": f"[{stateIndex+1}]",
            "vizRegionRect": json.dumps({"r":"viz","x":496,"y":148,"w":0,"h":0,"fieldVector":None}),
            "allowHoverActions": "false",
            "allowPromptText": "true",
            "allowWork": "false",
            "useInlineImages": "true"
        })
        tooltip = json.loads(r.json()["vqlCmdResponse"]["cmdResultList"][0]["commandReturn"]["tooltipText"])["htmlTooltip"]
        soup = BeautifulSoup(tooltip, "html.parser")
        rows = [ 
            t.find("tr").find_all("td")
            for t in soup.find_all("table")
        ]
        entry = { "state": state }
        for row in rows:
            if (row[0].text == "Mobility Index:"):
                entry["CMI"] = "".join([t.text.strip() for t in row[1:]])
            if row[0].text == "YoY (%):":
                entry["YoY"] = "".join([t.text.strip() for t in row[1:]])
        print(entry)
        data.append(entry)
    
    print(data)
    

    Try this on repl.it

    要获取县信息,它与使用select 端点的this post 相同,它为您提供与您在问题中链接的帖子格式相同的数据

    以下将提取所有县和州的数据:

    import requests
    from bs4 import BeautifulSoup
    import json
    import time
    
    data_host = "https://public.tableau.com"
    worksheet = "US Map - State - CMI"
    dashboard = "CMI"
    
    r = requests.get(
        f"{data_host}/views/CMI-2_0/CMI",
        params= {
            ":showVizHome":"no",
        }
    )
    soup = BeautifulSoup(r.text, "html.parser")
    
    tableauData = json.loads(soup.find("textarea",{"id": "tsConfigContainer"}).text)
    
    dataUrl = f'{data_host}{tableauData["vizql_root"]}/bootstrapSession/sessions/{tableauData["sessionid"]}'
    
    r = requests.post(dataUrl, data= {
        "sheet_id": tableauData["sheetId"],
    })
    data = []
    
    stateNames = ["Wyoming","Wisconsin","West Virginia","Washington","Virginia","Vermont","Utah","Texas","Tennessee","South Dakota","South Carolina","Rhode Island","Pennsylvania","Oregon","Oklahoma","Ohio","North Dakota","North Carolina","New York","New Mexico","New Jersey","New Hampshire","Nevada","Nebraska","Montana","Missouri","Mississippi","Minnesota","Michigan","Massachusetts","Maryland","Maine","Louisiana","Kentucky","Kansas","Iowa","Indiana","Illinois","Idaho","Georgia","Florida","District of Columbia","Delaware","Connecticut","Colorado","California","Arkansas","Arizona","Alabama"]
    
    for stateIndex, state in enumerate(stateNames):
        time.sleep(0.5) #for throttling
        r = requests.post(f'{data_host}{tableauData["vizql_root"]}/sessions/{tableauData["sessionid"]}/commands/tabsrv/render-tooltip-server',
            data = {
            "worksheet": worksheet,
            "dashboard": dashboard,
            "tupleIds": f"[{stateIndex+1}]",
            "vizRegionRect": json.dumps({"r":"viz","x":496,"y":148,"w":0,"h":0,"fieldVector":None}),
            "allowHoverActions": "false",
            "allowPromptText": "true",
            "allowWork": "false",
            "useInlineImages": "true"
        })
        tooltip = json.loads(r.json()["vqlCmdResponse"]["cmdResultList"][0]["commandReturn"]["tooltipText"])["htmlTooltip"]
        soup = BeautifulSoup(tooltip, "html.parser")
        rows = [ 
            t.find("tr").find_all("td")
            for t in soup.find_all("table")
        ]
        entry = { "state": state }
        for row in rows:
            if (row[0].text == "Mobility Index:"):
                entry["CMI"] = "".join([t.text.strip() for t in row[1:]])
            if row[0].text == "YoY (%):":
                entry["YoY"] = "".join([t.text.strip() for t in row[1:]])
    
        r = requests.post(f'{data_host}{tableauData["vizql_root"]}/sessions/{tableauData["sessionid"]}/commands/tabdoc/select',
            data = {
            "worksheet": worksheet,
            "dashboard": dashboard,
            "selection": json.dumps({
                "objectIds":[stateIndex+1],
                "selectionType":"tuples"
            }),
            "selectOptions": "select-options-simple"
        })
        entry["county_data"] = r.json()["vqlCmdResponse"]["layoutStatus"]["applicationPresModel"]["dataDictionary"]["dataSegments"]
        print(entry)
        data.append(entry)
    
    
    print(data)
    

    【讨论】:

      猜你喜欢
      • 2020-09-09
      • 2021-05-20
      • 1970-01-01
      • 2020-04-28
      • 2018-02-17
      • 2013-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多