【问题标题】:Node: Can't scrape a public tableau dashboard?节点:无法抓取公共画面仪表板?
【发布时间】:2020-07-11 11:39:28
【问题描述】:

所以我从question 复制了步骤并将其转换为 node.js

...
app.use('/', async (request, response) => {
    const fetchedSite = await fetch('https://public.tableau.com/views/COVID-19CasesandDeathsinthePhilippines_15866705872710/Home?%3Aembed=y&%3AshowVizHome=no&%3Adisplay_count=y&%3Adisplay_static_image=y&%3AbootstrapWhenNotified=true&%3Alanguage=en&:embed=y&:showVizHome=n&:apiID=host0#navType=0&navSrc=Parse')
    const siteText = await fetchedSite.text()
    const $ = cheerio.load(siteText)
    const tsConfigJson = JSON.parse($('#tsConfigContainer').text())

    const body = {
        sheet_id: tsConfigJson.sheetId
    }

    const getTableauData = await fetch(`https://public.tableau.com${tsConfigJson.vizql_root}/bootstrapSession/sessions/${tsConfigJson.sessionid}`, {
        method: 'POST',
        body: JSON.stringify(body)
    })

    return response.status(200).send(getTableauData)
...

我得到的唯一回应是这个

{"size":0,"timeout":0}

状态:500

statusText:内部服务器错误

我错过了什么吗?

【问题讨论】:

    标签: node.js web-scraping cheerio tableau-api


    【解决方案1】:

    问题是您尝试发送 json 而它需要是表单数据:

    const body = new URLSearchParams();
    body.append('sheet_id', tsConfigJson.sheetId);
    
    const tableauData = await fetch(`https://public.tableau.com${tsConfigJson.vizql_root}/bootstrapSession/sessions/${tsConfigJson.sessionid}`, {
        method: 'POST',
        body: body
    })
    

    获取数据的完整代码:

    const fetch = require('node-fetch');
    const cheerio = require('cheerio');
    
    const url = 'https://public.tableau.com/views/COVID-19CasesandDeathsinthePhilippines_15866705872710/Home?';
    const params = new URLSearchParams({ 
        ":embed": "y",
        ":showVizHome": "no",
        ":display_count": "y",
        ":display_static_image": "y",
        ":bootstrapWhenNotified": true,
        ":language": "en",
        ":embed": "y",
        ":showVizHome": "n",
        ":apiID": "host0" 
    });
    
    (async () => {
        const site = await fetch(url + params);
        var text = await site.text();
        const $ = cheerio.load(text);
        const tsConfigJson = JSON.parse($('#tsConfigContainer').text());
    
        const body = new URLSearchParams();
        body.append('sheet_id', tsConfigJson.sheetId);
    
        const tableauData = await fetch(`https://public.tableau.com${tsConfigJson.vizql_root}/bootstrapSession/sessions/${tsConfigJson.sessionid}`, {
            method: 'POST',
            body: body
        })
        text = await tableauData.text();
        var jsonRegex = /\d+;({.*})\d+;({.*})/g;
        var match = jsonRegex.exec(text);
        const info = JSON.parse(match[1]);
        const data = JSON.parse(match[2]);
        console.log(data.secondaryInfo.presModelMap.dataDictionary.presModelHolder.genDataDictionaryPresModel.dataSegments["0"].dataColumns)
    })();
    

    Try this on repl.it

    【讨论】:

    • 试试这个,谢谢!
    • @bertrandmartel - 尝试使用受信任的身份验证对常规 Tableau 服务器(非 Tableau 公共)执行此操作,并且对 site.text() 的调用不返回可以解析以获取 tsConfigContainer 的内容并且失败当试图得到它时。您是否有一个适用于常规 Tableau 服务器的示例?
    猜你喜欢
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    • 2019-11-23
    • 2021-01-20
    • 2021-01-23
    • 2023-02-03
    • 2021-06-20
    • 1970-01-01
    相关资源
    最近更新 更多