2013-07-02 49 views
20

Version: Python 2.7.3Python yêu cầu dữ liệu POST mã hóa

thư viện khác: Python-Các yêu cầu 1.2.3, jinja2 (2,6)

Tôi có một kịch bản mà nộp dữ liệu vào một diễn đàn và vấn đề là các ký tự không phải ascii xuất hiện dưới dạng rác. Ví dụ, một cái tên như André Téchiné xuất hiện như là André © Tà © chinà ©.

Dưới đây là cách dữ liệu được nộp:

1) Dữ liệu ban đầu được nạp từ một tập tin CSV UTF-8 mã hóa như sau:

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 là từ dưới cùng của trang tài liệu Python CSV: http://docs.python.org/2/library/csv.html

Khi tôi nhập tên mục trong trình thông dịch, tôi thấy tên là u'Andr\xe9 T\xe9chin\xe9'.

2) Tiếp theo, tôi làm cho dữ liệu thông qua jinja2:

tpl = tpl_env.get_template(u'forumpost.html') 
rendered = tpl.render(entries=entries) 

Khi tôi gõ tên render trong thông dịch viên tôi thấy một lần nữa giống nhau: u'Andr\xe9 T\xe9chin\xe9'

Bây giờ, nếu tôi viết biến render để một tên tập tin như thế này, nó sẽ hiển thị một cách chính xác:

with codecs.open('out.txt', 'a', 'utf-8') as f: 
    f.write(rendered) 

Nhưng tôi phải gửi nó đến diễn đàn:

3) Trong các mã yêu cầu POST tôi có:

params = {u'post': rendered} 
headers = {u'content-type': u'application/x-www-form-urlencoded'} 
session.post(posturl, data=params, headers=headers, cookies=session.cookies) 

phiên là một phiên yêu cầu.

Và tên được hiển thị bị hỏng trong bài đăng trên diễn đàn. Tôi đã thử những điều sau đây:

  • header Bỏ
  • Encode render như rendered.encode ('utf-8') (tương tự kết quả)
  • render = urllib.quote_plus (render) (đi ra như tất cả% XY)

Nếu tôi gõ rendered.encode ('utf-8') tôi thấy như sau:

'Andr\xc3\xa9 T\xc3\xa9chin\xc3\xa9' 

Làm sao tôi khắc phục vấn đề? Cảm ơn.

Trả lời

24

Khách hàng của bạn cư xử như nó nên ví dụchạy nc -l 8888 như một máy chủ và thực hiện một yêu cầu:

import requests 

requests.post('http://localhost:8888', data={u'post': u'Andr\xe9 T\xe9chin\xe9'}) 

show:

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 

Bạn có thể kiểm tra điều đó là đúng:

>>> import urllib 
>>> urllib.unquote_plus(b"Andr%C3%A9+T%C3%A9chin%C3%A9").decode('utf-8') 
u'Andr\xe9 T\xe9chin\xe9' 
  • kiểm tra server giải mã yêu cầu đúng. Bạn có thể thử để xác định charset:

    headers = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"} 
    

    cơ thể chỉ chứa ký tự ascii vì vậy không nên bị tổn thương và các máy chủ chính xác sẽ bỏ qua bất kỳ thông số cho x-www-form-urlencoded loại anyway. Tìm kiếm thông tin chi tiết đẫm máu trong URL-encoded form data

  • kiểm tra vấn đề này không phải là một vật phẩm trưng bày ví dụ, giá trị là đúng nhưng nó sẽ hiển thị không đúng

+0

"kiểm tra vấn đề này không phải là một vật phẩm trưng bày ví dụ, giá trị là đúng nhưng nó hiển thị không chính xác "- Cảm ơn bạn. Đó chính là vấn đề! Rất tiếc, đó là diễn đàn công khai và tôi không thể thay đổi mã hóa mặc định. Nó đáp ứng với mã hóa iso-8859-1. Tôi có thể sử dụng rendered.encode ('iso-8859-1') hay điều đó sẽ phá vỡ mọi thứ? Cảm ơn. – TheMagician

+1

cố gắng đặt bộ ký tự trong tiêu đề – jfs

+0

Điều đó không hoạt động. – TheMagician

1

Cố gắng giải mã thành utf8:

unicode(my_string_variable, "utf8") 

hoặc giải mã và mã hóa:

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') 
Các vấn đề liên quan