Python 请求编码 POST 数据
Posted
技术标签:
【中文标题】Python 请求编码 POST 数据【英文标题】:Python Requests encoding POST data 【发布时间】:2013-06-29 08:24:30 【问题描述】:版本:Python 2.7.3
其他库:Python-Requests 1.2.3、jinja2 (2.6)
我有一个向论坛提交数据的脚本,但问题是非 ascii 字符显示为垃圾。例如,像 André Téchiné 这样的名字出现为 André© Téchiné。
提交数据的方式如下:
1) 数据最初是从 UTF-8 编码的 CSV 文件加载的,如下所示:
entries = []
with codecs.open(filename, 'r', 'utf-8') as f:
for row in unicode_csv_reader(f.readlines()[1:]):
entries.append(dict(zip(csv_header, row)))
unicode_csv_reader 来自 Python CSV 文档页面底部:http://docs.python.org/2/library/csv.html
当我在解释器中输入条目名称时,我看到名称为u'Andr\xe9 T\xe9chin\xe9'
。
2) 接下来我通过 jinja2 渲染数据:
tpl = tpl_env.get_template(u'forumpost.html')
rendered = tpl.render(entries=entries)
当我输入在解释器中呈现的名称时,我再次看到相同的内容:u'Andr\xe9 T\xe9chin\xe9'
现在,如果我将渲染变量写入这样的文件名,它会正确显示:
with codecs.open('out.txt', 'a', 'utf-8') as f:
f.write(rendered)
但我必须发到论坛:
3) 在我的 POST 请求代码中:
params = u'post': rendered
headers = u'content-type': u'application/x-www-form-urlencoded'
session.post(posturl, data=params, headers=headers, cookies=session.cookies)
会话是一个请求会话。
并且该名称在论坛帖子中显示已损坏。我尝试了以下方法:
省略标题 编码呈现为rendered.encode('utf-8')(结果相同) rendered = urllib.quote_plus(rendered) (全部显示为 %XY)如果我输入 render.encode('utf-8') 我会看到以下内容:
'Andr\xc3\xa9 T\xc3\xa9chin\xc3\xa9'
我该如何解决这个问题?谢谢。
【问题讨论】:
【参考方案1】:您的客户的行为应有尽有,例如将nc -l 8888
作为服务器运行并发出请求:
import requests
requests.post('http://localhost:8888', data=u'post': u'Andr\xe9 T\xe9chin\xe9')
显示:
POST / HTTP/1.1
Host: localhost:8888
Content-Length: 33
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate, compress
Accept: */*
User-Agent: python-requests/1.2.3 CPython/2.7.3
post=Andr%C3%A9+T%C3%A9chin%C3%A9
您可以检查它是否正确:
>>> import urllib
>>> urllib.unquote_plus(b"Andr%C3%A9+T%C3%A9chin%C3%A9").decode('utf-8')
u'Andr\xe9 T\xe9chin\xe9'
检查服务器是否正确解码请求。您可以尝试指定字符集:
headers = "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
正文仅包含 ascii 字符,因此它不应该受到伤害,并且正确的服务器无论如何都会忽略 x-www-form-urlencoded
类型的任何参数。在URL-encoded form data中寻找血腥细节
检查问题不是显示伪影,即值正确但显示不正确
【讨论】:
“检查问题不是显示伪影,即值正确但显示不正确” - 谢谢。那就是问题所在!不幸的是,这是一个公共论坛,我无法更改默认编码。它以 iso-8859-1 编码响应。我可以使用 render.encode('iso-8859-1') 还是会破坏?谢谢。 尝试在标题中设置字符集 发送它作为 render.encode('iso-8859-1') 似乎工作,所以我会使用它。我将您的答案标记为正确,因为它指向了正确的方向。谢谢。 对于发现此问题的任何其他人,您可以使用urllib.parse.quote_from_bytes
和 urllib.parse.unquote_to_bytes
通过网络发送字节类型,而不必担心编码问题。
@MicahSmith:这个问题有python-2.7 标签。那里没有urllib.parse
。无论如何,输入是 Unicode(应该使用 Unicode 来表示程序中的文本)。旁注:unquote_plus()
在这里用于让 OP 相信 requests.post()
可以正常工作——您不要在实际代码中使用它。【参考方案2】:
尝试解码成utf8:
unicode(my_string_variable, "utf8")
或解码和编码:
sometext = gettextfromsomewhere().decode('utf-8')
env = jinja2.Environment(loader=jinja2.PackageLoader('jinjaapplication', 'templates'))
template = env.get_template('mypage.html')
print template.render( sometext = sometext ).encode('utf-8')
【讨论】:
以上是关于Python 请求编码 POST 数据的主要内容,如果未能解决你的问题,请参考以下文章
python+pytest接口自动化框架-requests发送post请求
python3+requests:post请求四种传送正文方式(详解)