Python API自动化遇TypeError:string indices must be integers, not 'str'
问题分析与解决
核心错误排查
1. TypeError: string indices must be integers, not 'str'
这个错误本质是把字符串当成字典/列表进行索引访问。比如你可能误将接口响应文本(未解析的response.text)当作JSON字典,尝试用response['key']取值;或是传递给更新函数的Cookie格式错误,把纯字符串(比如"token=xxx")当成了字典格式的请求头。
2. 'int' object is not subscriptable / 'dict' object is not callable
- 前者是对整数类型的预订ID误用了索引,比如写了
booking_id['id'],但booking_id本身就是int类型的ID值; - 后者是把字典对象当成函数调用,比如
auth_cookie(),但auth_cookie是存储Cookie的字典,不能加括号执行。
解决方案:正确处理预订ID与参数传递
1. 正确获取并转换预订ID
创建预订接口返回的JSON结构通常是{"bookingid": 123, "booking": {...}},直接提取int类型的bookingid,再通过字符串格式化拼入URL(f-string会自动转换int为字符串):
def create_booking(): # 发送创建预订请求 response = requests.post("https://restful-booker.herokuapp.com/booking", json=booking_payload) booking_result = response.json() # 提取int类型的预订ID booking_id = booking_result['bookingid'] return booking_id # 拼接更新接口URL update_url = f"https://restful-booker.herokuapp.com/booking/{booking_id}"
2. 正确传递认证Cookie
认证接口返回{"token": "abc123"},需组装成字典格式的请求头Cookie,避免传递纯字符串:
def get_auth_cookie(): response = requests.post("https://restful-booker.herokuapp.com/auth", json={"username": "admin", "password": "password123"}) token = response.json()['token'] # 返回符合请求头要求的字典格式Cookie return {"Cookie": f"token={token}"} # 更新预订函数中使用 def update_booking(auth_cookie, booking_id): update_url = f"https://restful-booker.herokuapp.com/booking/{booking_id}" update_payload = {"firstname": "Updated", "lastname": "Test"} response = requests.put(update_url, json=update_payload, headers=auth_cookie) return response.json()
3. 规避常见操作误区
- 不要对int类型的预订ID用索引,比如
booking_id['bookingid']是错误写法,booking_id本身就是ID值; - 不要把字典当函数调用,比如
auth_cookie()是错误的,直接传入auth_cookie作为headers参数即可; - 所有接口响应务必用
.json()解析为字典后再操作,不要直接用response.text做索引。
代码整体优化建议
- 封装公共请求方法:减少重复代码,统一处理异常和响应解析:
def send_request(method, url, headers=None, json=None): try: response = requests.request(method, url, headers=headers, json=json) response.raise_for_status() # 主动抛出HTTP状态码错误 return response.json() except requests.exceptions.RequestException as e: print(f"请求失败: {str(e)}") return None
- 提取常量到配置:把基础URL、用户名密码等放到单独文件(比如
config.py),便于维护; - 增加日志记录:用
logging模块记录请求URL、参数、响应内容,方便排查问题; - 参数校验:在函数入口对预订ID(确保是int/str)、Cookie(确保是字典)做简单校验,提前发现错误;
- 用类封装业务:把Restful Booker的操作封装成类,统一管理认证状态,避免重复传递Cookie:
class BookerAPI: def __init__(self, base_url): self.base_url = base_url self.auth_cookie = None def auth(self, username, password): url = f"{self.base_url}/auth" data = send_request("POST", url, json={"username": username, "password": password}) if data: self.auth_cookie = {"Cookie": f"token={data['token']}"} def create_booking(self, booking_data): url = f"{self.base_url}/booking" data = send_request("POST", url, json=booking_data) return data['bookingid'] if data else None def update_booking(self, booking_id, update_data): if not self.auth_cookie: print("请先完成认证") return None url = f"{self.base_url}/booking/{booking_id}" return send_request("PUT", url, headers=self.auth_cookie, json=update_data)
内容的提问来源于stack exchange,提问作者bull1t
相关产品推荐
相关产品推荐

