You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python从Salesforce取数遇TooManyRedirects错误的解决咨询

Salesforce报表导出请求触发TooManyRedirects错误

之前正常运行的Python代码,近期通过requests请求Salesforce Lightning域名导出报表CSV时,报错TooManyRedirects: Exceeded 30 redirects,代码和错误信息如下:

代码片段

from datetime import datetime
import pandas as pd
from io import StringIO
import requests
from simple_salesforce import Salesforce

start_time = datetime.now()

# 连接Salesforce
sf = Salesforce(username='-----',password='-----',security_token='-----')

# Salesforce报表ID
Accepted_Cases = '00O6N000000ZkQiUAK'
New_Case = '00O6N000000SkDaUAK'
WF_Case_Dispostions  = '00O6N000000SkDVUA0'
Total_Reply_by_Agent = '00O6N000000ZkQTUA0'
#Offered_Cases_T2 = '00O6N000000SqclUAC'

# 导出报表CSV
Accepted_Cases_df = pd.read_csv(StringIO(requests.get(f'https://altayyargroup.lightning.force.com/{Accepted_Cases}?isdtp=p1&export=1&enc=UTF-8&xf=csv', headers=sf.headers, cookies={'sid': sf.session_id}).content.decode('utf-8')))
New_Case_df = pd.read_csv(StringIO(requests.get(f'https://altayyargroup.lightning.force.com/{New_Case}?isdtp=p1&export=1&enc=UTF-8&xf=csv', headers=sf.headers, cookies={'sid': sf.session_id}).content.decode('utf-8')))
WF_Case_Dispostions_df = pd.read_csv(StringIO(requests.get(f'https://altayyargroup.lightning.force.com/{WF_Case_Dispostions}?isdtp=p1&export=1&enc=UTF-8&xf=csv', headers=sf.headers, cookies={'sid': sf.session_id}).content.decode('utf-8')))
Total_Reply_by_Agent_df = pd.read_csv(StringIO(requests.get(f'https://altayyargroup.lightning.force.com/{Total_Reply_by_Agent}?isdtp=p1&export=1&enc=UTF-8&xf=csv', headers=sf.headers, cookies={'sid': sf.session_id}).content.decode('utf-8')))
#Offered_Cases_T2_df = pd.read_csv(StringIO(requests.get(f'https://altayyargroup.lightning.force.com/{Offered_Cases_T2}?isdtp=p1&export=1&enc=UTF-8&xf=csv', headers=sf.headers, cookies={'sid': sf.session_id}).content.decode('utf-8')))

end_time = datetime.now()
print(f'Duration: {end_time - start_time}')

错误信息

TooManyRedirects                          Traceback (most recent call last)
~\\AppData\\Local\\Temp/ipykernel_13988/64063902.py in <module>
     13 # Salesforce Reports
     14 #Accepted_Cases_df = pd.read_csv(StringIO(requests.get(f'https://altayyargroup.lightning.force.com/{Accepted_Cases}?isdtp=p1&export=1&enc=UTF-8&xf=csv', headers=sf.headers, cookies={'sid': sf.session_id}).content.decode('utf-8')))
---> 15 New_Case_df = pd.read_csv(StringIO(requests.get(f'https://altayyargroup.lightning.force.com/{New_Case}?isdtp=p1&export=1&enc=UTF-8&xf=csv', headers=sf.headers, cookies={'sid': sf.session_id}).content.decode('utf-8')))
     16 #WF_Case_Dispostions_df = pd.read_csv(StringIO(requests.get(f'https://altayyargroup.lightning.force.com/{WF_Case_Dispostions}?isdtp=p1&export=1&enc=UTF-8&xf=csv', headers=sf.headers, cookies={'sid': sf.session_id}).content.decode('utf-8')))
     17 #Total_Reply_by_Agent_df = pd.read_csv(StringIO(requests.get(f'https://altayyargroup.lightning.force.com/{Total_Reply_by_Agent}?isdtp=p1&export=1&enc=UTF-8&xf=csv', headers=sf.headers, cookies={'sid': sf.session_id}).content.decode('utf-8')))

~\\anaconda3\\lib\\site-packages\\requests\\api.py in get(url, params, **kwargs)
     73     """
     74 
---> 75     return request('get', url, params=params, **kwargs)
     76 
     77 

~\\anaconda3\\lib\\site-packages\\requests\\api.py in request(method, url, **kwargs)
     59     # cases, and look like a memory leak in others.
     60     with sessions.Session() as session:
---> 61         return session.request(method=method, url=url, **kwargs)
     62 
     63 

~\\anaconda3\\lib\\site-packages\\requests\\sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
    540         }
    541         send_kwargs.update(settings)
---> 542         resp = self.send(prep, **send_kwargs)
    543 
    544         return resp

~\\anaconda3\\lib\\site-packages\\requests\\sessions.py in send(self, request, **kwargs)
    675             # Redirect resolving generator.
    676             gen = self.resolve_redirects(r, request, **kwargs)
---> 677             history = [resp for resp in gen]
    678         else:
    679             history = []

~\\anaconda3\\lib\\site-packages\\requests\\sessions.py in <listcomp>(.0)
    675             # Redirect resolving generator.
    676             gen = self.resolve_redirects(r, request, **kwargs)
---> 677             history = [resp for resp in gen]
    678         else:
    679             history = []

~\\anaconda3\\lib\\site-packages\\requests\\sessions.py in resolve_redirects(self, resp, req, stream, timeout, verify, cert, proxies, yield_requests, **adapter_kwargs)
    164 
    165             if len(resp.history) >= self.max_redirects:
---> 166                 raise TooManyRedirects('Exceeded {} redirects.'.format(self.max_redirects), response=resp)
    167 
    168             # Release the connection back into the pool.

TooManyRedirects: Exceeded 30 redirects.

解决方案

1. 改用Simple-Salesforce内置报表导出方法

直接使用simple-salesforce库提供的report方法,无需手动构造URL和处理认证,自动适配正确的API端点,彻底避免重定向问题:

# 替换原有报表请求代码
Accepted_Cases_df = pd.read_csv(StringIO(sf.report(Accepted_Cases, fmt='csv')))
New_Case_df = pd.read_csv(StringIO(sf.report(New_Case, fmt='csv')))
WF_Case_Dispostions_df = pd.read_csv(StringIO(sf.report(WF_Case_Dispostions, fmt='csv')))
Total_Reply_by_Agent_df = pd.read_csv(StringIO(sf.report(Total_Reply_by_Agent, fmt='csv')))

2. 更换为经典版Salesforce域名

如果坚持手动构造URL,将Lightning域名lightning.force.com替换为经典域名my.salesforce.com,并移除isdtp=p1参数(该参数是Lightning界面内部标识,报表导出不需要):

# 修改后的URL模板
url_template = 'https://altayyargroup.my.salesforce.com/{report_id}?export=1&enc=UTF-8&xf=csv'
# 示例请求
New_Case_df = pd.read_csv(StringIO(requests.get(url_template.format(report_id=New_Case), headers=sf.headers, cookies={'sid': sf.session_id}).content.decode('utf-8')))

3. 排查会话有效性

  • 执行print(sf.describe())测试连接是否正常,若返回Salesforce元数据说明认证有效;
  • 若会话过期,重新初始化Salesforce对象,确认用户名、密码、安全令牌无误。

4. 临时调试(不推荐生产环境使用)

若需定位重定向链,可临时提高重定向次数上限并开启调试日志:

import logging
import http.client

http.client.HTTPConnection.debuglevel = 1
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

# 请求时提高重定向次数
response = requests.get(url, headers=sf.headers, cookies={'sid': sf.session_id}, max_redirects=50)

通过日志可查看每一次重定向的目标URL,定位循环重定向的根源。


内容的提问来源于stack exchange,提问作者Mahmoud Badr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:01:19