使用请求和基本身份验证,使用python从https tableau服务器下载csv文件

2024-09-29 17:19:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个tableau 10.0服务器。我在https://example.com/views/SomeReport/Totals有一个视图。在浏览器中,如果我导航到https://example.com/views/SomeReport/Totals.csv,系统会提示我登录,然后将视图作为csv文件下载。在

我正试图用python下载这个相同的文件

细节

  • 表10.0
  • python 2.7
  • 窗户上的画面
  • MacOSX El capitan上运行的python

以下是我尝试的:

        tableau_file_path = '{tableau_path}{tableau_view}{file_ext}'.format(**cur_file)
        local_path = cur_file['local_path']
        user = 'xxxx'
        password = 'xxxx'

        # print tableau_file_path  # outputs https://example.com/views/SomeReport/Totals.csv
        # print local_path         # outputs ../generated_resources/Some Folder Name/Totals.csv 

        r = requests.get(tableau_file_path, auth=HTTPBasicAuth(user, password), stream=True, timeout=5)
        # also tried auth=(user, password)
        print r.status_code   # outputs 401
        if r.status_code == 200:
            with open(local_path, 'wb') as f: 
                f.write(r.content)

我觉得这应该管用,但是不行。我得到状态的401

如果我从路径中删除.csv,它就可以工作了,我确实得到了实际的tableau仪表板页面。但我需要csv文件而不是tableau仪表板上的html

我直接从我的代码中复制用户名和密码,并将它们粘贴到浏览器中弹出的表单中,而creds的工作似乎排除了错误creds的问题。在

这适用于普通网页,但在点击url提示下载文件时不起作用。如何使用文件下载来实现这一点?

注意我对使用python下载文件的其他方法持开放态度


Tags: 文件csvpathhttpscomexamplelocalpassword
2条回答

我要说的是,Tableau不是在做HTTP基本身份验证,而是有自己的方法。所以当你试图通过请求访问这个东西时,它会拒绝它,因为它不知道如何像那样授权。在

当你以人的身份访问它时,它知道要将你重定向到他们的登录页面,并完成整个“登录流程”,最后将你重定向到正确的下载页面。然而,requests试图清楚地将自己标识为robot,并使用一个特殊的UserAgent字符串(我相信是“requests”),这就是为什么服务器决定返回一个直接向上的401。在

根据您的用例,您可以手动登录,查看Tableau正在设置哪些cookie,并在请求中包含这些cookie。 您还可以将用户代理更改为浏览器代理(在绝大多数情况下,它们以“Mozilla 5.0/”开头),然后查看是否下载登录页面。如果是这样的话,你可以对他们的一些登录过程进行反向工程,以了解他们如何提交用户和密码,以及如何重定向到你想要的页面。之后,您很可能会向他们的登录基础设施发布一个包含这些数据和所需重定向的帖子。在

Tableau公开了一个restapi,可以用来下载csv文件。API端点是https://MY-SERVER/api/VERSION_NUM/auth/signin,其中VERSION_NUM取决于tableau服务器的版本,API版本和tableau服务器版本的映射可以找到here。为了使身份验证成功工作,您需要使用上面提到的API端点获取一个令牌。然后可以在头参数'X-tableau-auth'中传递此标记。代码如下:

import requests, json
from config import USERNAME, PASSWORD, SERVER_NAME

# NOTE! Substitute your own values for the following variables
server_name = SERVER_NAME # Name or IP address of your installation of Tableau Server
user_name = USERNAME    # User name to sign in as (e.g. admin)
password = PASSWORD
site_url_id = ""          # Site to sign in to. An empty string is used to specify the default site.

signin_url = "http://{}/api/3.1/auth/signin".format(server_name)

csv_url = "https://{}/#/views/Test/Dash/A.csv".format(server_name)

payload = { "credentials": { "name": user_name, "password": password, "site": {"contentUrl": site_url_id }}}

headers = {
  'accept': 'text/csv,application/json',
  'content-type': 'application/json'
}

# Send the request to the server
req = requests.post(signin_url, json=payload, headers=headers)
req.raise_for_status()

# Get the response
response = json.loads(req.content)

# Parse the response JSON. The response body will look similar
# to the following example:
#
# {
#    "credentials": {
#        "site": {
#            "id": "xxxxxxxxxx-xxxx-xxxx-xxxxxxxxxx",
#            "contentUrl": ""
#        },
#        "user": {
#            "id": "xxxxxxxxxx-xxxx-xxxx-xxxxxxxxxx"
#        },
#         "token": "AUTH-TOKEN"
#    }
# }


# Get the authentication token from the <credentials> element
token = response["credentials"]["token"]

# Get the site ID from the <site> element
site_id = response["credentials"]["site"]["id"]

print('Sign in successful!')
print('\tToken: {token}'.format(token=token))
print('\tSite ID: {site_id}'.format(site_id=site_id))

# Set the authentication header using the token returned by the Sign In method.
headers['X-tableau-auth']=token


csv_req = requests.get(csv_url, headers=headers)
# ... Make other calls here ...

csv_req.raise_for_status() 
print(csv_req.status_code) #200

with open('something.csv', 'wb') as f:
  f.write(csv_req.content)

这通过了身份验证问题,但我得到的是响应中的页面源,而不是CSV文件

页面来源:

^{pr2}$

如果有人能指导我如何获得文本/csv响应而不是html,这将是非常有帮助的。在

相关问题 更多 >

    热门问题