使用变量设置WebKitFormBoundary导致POST请求失效求助
修复自定义WebKitFormBoundary导致POST请求失效的问题
我有一段能成功发送POST请求的Python代码,返回响应تم تسجيل الطلب بنجاح(意为“注册成功”)。为简化代码,尝试用变量定义WebKitFormBoundary的值,但修改后的代码无法正常发起请求,请问该如何解决?
原成功代码
import requests cookies = {'BNES_JSESSIONID': 'R2aVMfNrT78PyhSgyqW6Kj7BlBMOR7cQqB+Tq7wGQl34xSno1KKqpymu/ZLhny2lshfxmOnZiFy8Zbvw+vcSPCPOAALQXhOdFcYX61dU7WDszMVLkwHKehvnHfmubbwQG5BhwWAjqWJlKz22mi985kyPwyYEwx8y'} headers = {'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryB6r6VIYgOSHWqj5I'} data = '------WebKitFormBoundaryB6r6VIYgOSHWqj5I\r\nContent-Disposition: form-data; name="selectAser"\r\n\r\n211053300\r\n------WebKitFormBoundaryB6r6VIYgOSHWqj5I\r\nContent-Disposition: form-data; name="phoneNo"\r\n\r\n55075052\r\n------WebKitFormBoundaryB6r6VIYgOSHWqj5I\r\nContent-Disposition: form-data; name="selectAsed"\r\n\r\n120987470-1\r\n------WebKitFormBoundaryB6r6VIYgOSHWqj5I\r\nContent-Disposition: form-data; name="comReg"\r\n\r\n\r\n------WebKitFormBoundaryB6r6VIYgOSHWqj5I\r\nContent-Disposition: form-data; name="bankType"\r\n\r\n1850\r\n------WebKitFormBoundaryB6r6VIYgOSHWqj5I\r\nContent-Disposition: form-data; name="attachments"; filename=""\r\nContent-Type: application/octet-stream\r\n\r\n\r\n------WebKitFormBoundaryB6r6VIYgOSHWqj5I\r\nContent-Disposition: form-data; name="searchType"\r\n\r\n0745\r\n------WebKitFormBoundaryB6r6VIYgOSHWqj5I--\r\n' response = requests.post('https://eservices.gov./', cookies=cookies, headers=headers, data=data) print(response.text)
修改后失效的代码
import requests def post_with_custom_boundary(c_boundary): url = 'https://eservices.gov./' cookies = {'BNES_JSESSIONID': 'FBVxGgtjjJhDGmcnG/XOglUeuJlG/mwpJH9+ICQw/bL3/2Y383HWR4f+WzRXsJBG5jHf33qCsgMBOHLeTKxJRBwlkrkKE1tGbdywVgdikWhC4VcCUd1yIIYJBFm4m/60lfkGqvgk+UfaMbPKe3CUVRvsTaMCLn+A'} headers = {'Content-Type': f'multipart/form-data; boundary={c_boundary}'} data = f'{c_boundary}\r\nContent-Disposition: form-data; name="selectAser"\r\n\r\n211053300\r\n{c_boundary}\r\nContent-Disposition: form-data; name="phoneNo"\r\n\r\n55075052\r\n{c_boundary}\r\nContent-Disposition: form-data; name="selectAsed"\r\n\r\n120987470-1\r\n{c_boundary}\r\nContent-Disposition: form-data; name="comReg"\r\n\r\n\r\n{c_boundary}\r\nContent-Disposition: form-data; name="bankType"\r\n\r\n1850\r\n{c_boundary}\r\nContent-Disposition: form-data; name="attachments"; filename=""\r\nContent-Type: application/octet-stream\r\n\r\n\r\n{c_boundary}\r\nContent-Disposition: form-data; name="searchType"\r\n\r\n0745\r\n{c_boundary}--\r\n' response = requests.post(url, cookies=cookies, headers=headers, data=data) print(response.text) c_boundary = '------WebKitFormBoundaryg3LDfuaso7lfkkvj' post_with_custom_boundary(c_boundary)
问题原因
对比两段代码的boundary格式:
- 原代码中,
headers里的boundary值是4个短横线开头:----WebKitFormBoundaryB6r6VIYgOSHWqj5I - 而
data里的每个分隔符是8个短横线开头:------WebKitFormBoundaryB6r6VIYgOSHWqj5I
修改后的代码把c_boundary定义为8个短横线开头,直接放到headers里,导致服务器收到的Content-Type中的boundary值和请求体里的分隔符不匹配,无法正确解析multipart数据。
解决方案
需要保证headers中的boundary值是请求体分隔符去掉前4个短横线的版本,有两种实现方式:
方式1:拆分boundary前缀和主体
import requests def post_with_custom_boundary(boundary_body): url = 'https://eservices.gov./' cookies = {'BNES_JSESSIONID': 'FBVxGgtjjJhDGmcnG/XOglUeuJlG/mwpJH9+ICQw/bL3/2Y383HWR4f+WzRXsJBG5jHf33qCsgMBOHLeTKxJRBwlkrkKE1tGbdywVgdikWhC4VcCUd1yIIYJBFm4m/60lfkGqvgk+UfaMbPKe3CUVRvsTaMCLn+A'} # header里用4个短横线+主体 headers = {'Content-Type': f'multipart/form-data; boundary=----{boundary_body}'} # 请求体里用8个短横线+主体 boundary = f'------{boundary_body}' data = f'{boundary}\r\nContent-Disposition: form-data; name="selectAser"\r\n\r\n211053300\r\n{boundary}\r\nContent-Disposition: form-data; name="phoneNo"\r\n\r\n55075052\r\n{boundary}\r\nContent-Disposition: form-data; name="selectAsed"\r\n\r\n120987470-1\r\n{boundary}\r\nContent-Disposition: form-data; name="comReg"\r\n\r\n\r\n{boundary}\r\nContent-Disposition: form-data; name="bankType"\r\n\r\n1850\r\n{boundary}\r\nContent-Disposition: form-data; name="attachments"; filename=""\r\nContent-Type: application/octet-stream\r\n\r\n\r\n{boundary}\r\nContent-Disposition: form-data; name="searchType"\r\n\r\n0745\r\n{boundary}--\r\n' response = requests.post(url, cookies=cookies, headers=headers, data=data) print(response.text) # 只传boundary主体部分 boundary_body = 'WebKitFormBoundaryg3LDfuaso7lfkkvj' post_with_custom_boundary(boundary_body)
方式2:对传入的c_boundary做截取
如果想保留原变量定义方式,直接截取前4个短横线后的部分放到header里:
import requests def post_with_custom_boundary(c_boundary): url = 'https://eservices.gov./' cookies = {'BNES_JSESSIONID': 'FBVxGgtjjJhDGmcnG/XOglUeuJlG/mwpJH9+ICQw/bL3/2Y383HWR4f+WzRXsJBG5jHf33qCsgMBOHLeTKxJRBwlkrkKE1tGbdywVgdikWhC4VcCUd1yIIYJBFm4m/60lfkGqvgk+UfaMbPKe3CUVRvsTaMCLn+A'} # 截取c_boundary去掉前4个短横线的部分 headers = {'Content-Type': f'multipart/form-data; boundary={c_boundary[4:]}'} data = f'{c_boundary}\r\nContent-Disposition: form-data; name="selectAser"\r\n\r\n211053300\r\n{c_boundary}\r\nContent-Disposition: form-data; name="phoneNo"\r\n\r\n55075052\r\n{c_boundary}\r\nContent-Disposition: form-data; name="selectAsed"\r\n\r\n120987470-1\r\n{c_boundary}\r\nContent-Disposition: form-data; name="comReg"\r\n\r\n\r\n{c_boundary}\r\nContent-Disposition: form-data; name="bankType"\r\n\r\n1850\r\n{c_boundary}\r\nContent-Disposition: form-data; name="attachments"; filename=""\r\nContent-Type: application/octet-stream\r\n\r\n\r\n{c_boundary}\r\nContent-Disposition: form-data; name="searchType"\r\n\r\n0745\r\n{c_boundary}--\r\n' response = requests.post(url, cookies=cookies, headers=headers, data=data) print(response.text) c_boundary = '------WebKitFormBoundaryg3LDfuaso7lfkkvj' post_with_custom_boundary(c_boundary)
额外建议
其实requests库本身支持自动处理multipart/form-data请求,不需要手动拼接boundary和请求体,用files参数可以更简洁,避免手动拼接出错:
import requests url = 'https://eservices.gov./' cookies = {'BNES_JSESSIONID': 'FBVxGgtjjJhDGmcnG/XOglUeuJlG/mwpJH9+ICQw/bL3/2Y383HWR4f+WzRXsJBG5jHf33qCsgMBOHLeTKxJRBwlkrkKE1tGbdywVgdikWhC4VcCUd1yIIYJBFm4m/60lfkGqvgk+UfaMbPKe3CUVRvsTaMCLn+A'} # 构造表单数据 form_data = { 'selectAser': ('', '211053300'), 'phoneNo': ('', '55075052'), 'selectAsed': ('', '120987470-1'), 'comReg': ('', ''), 'bankType': ('', '1850'), 'attachments': ('', '', 'application/octet-stream'), 'searchType': ('', '0745') } response = requests.post(url, cookies=cookies, files=form_data) print(response.text)
这种方式requests会自动生成正确的boundary,无需手动处理,代码更简洁可靠。
内容的提问来源于stack exchange,提问作者YasserKhalil
相关产品推荐
相关产品推荐

