Найти - Пользователи
Полная версия: [РЕШЕНО] Python 3 POST-запрос multipart/form-data в requests с кодировкой Windows-1251
Начало » Web » [РЕШЕНО] Python 3 POST-запрос multipart/form-data в requests с кодировкой Windows-1251
1 2
omatic
Доброго времени суток уважаемые форумчане.

Пробую тут передать данные на страницу с формами(multipart/form-data) на сайт. Столкнулся с проблемой кодировок. Итак суть:

1. сайт в кодировке Windows-1251
2. файл, в котором идут поля которые нужно передать в кодировке Windows-1251
3. Пример скрипта, тоже в cp1251, запускается на FreeBSD:

#!/usr/bin/env python3
# -*- coding: cp1251 -*-
import requests
def main():
	f = open('/var/ftp/file.txt','r', encoding='cp1251')
	s_cp1251 = f.read()
	
	postdata = {
		"TopicTitle" : s_cp1251,
		"TopicDesc" : 'тест',
		"Post" : 'тест'
	}
	headers = {
		'User-Agent' : 'Mozilla/5.0 (Windows NT 5.1; rv:20.0) Gecko/20100101 Firefox/20.0',
		'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
		'Accept-Language' : 'en-US,en;q=0.5',
		'Accept-Encoding' : 'gzip, deflate',
		'Connection' : 'keep-alive'
	}
	
	s = requests.Session()
	s.encoding = 'Windows-1251'
	q = s.post('http://site.com/index.php?', headers=headers, data=postdata, files={'':''})
	print(q.status_code)
if __name__ == '__main__':
    main()

Данные передает, но в форме странный текст: тест

Я так понимаю, POST по стандарту передает в utf-8, вот почему такой результат. Как заставить передавать его в Windows-1251 ?

Буду благодарен за любой совет или пинок в правильную сторону


———
П.С. кому интересно решение и нет охоты читать все ответы, то тут все просто, возможности передать cp1251 через multipart/form-data в Python 3/requests пока нет. Только UTF-8. Так что передавайте data=postdata через form-urlencoded
ZZZ

Я уже говорил когда-то... Тех, кто использует восьмибитные кодировки, надо сжигать на кострах.

omatic
ZZZ, я тоже за использование юникода и utf-8, но на сайте кодировка Windows-1251, и этого я изменить не могу, вот и пробую выкрутиться, что бы хоть как-то туда автоматический постинг прикрутить.
reclosedev
omatic
f = open('/var/ftp/file.txt','r', encoding='cp1251')
s_cp1251 = f.read()
На самом деле в s_cp1251 находится Юникод, а requests его заботливо перекодирует в utf-8 при отправке.

Чтобы отправить текст в своей кодировке, нужно передавать байтовые объекты:
import requests
 
text = "Привет мир"
data = {"field": text.encode("cp1251")}
r = requests.post("http://httpbin.org/post", data=data, files={'':''})
print(r.request.body)

В вашем случае, текст из файла нужно прочесть в бинарном режиме, без указания кодировки. А значения остальных ключей в data нужно перекодировать вручную
"тест".encode("cp1251")
omatic
reclosedev, Спасибо, другой вопрос, передаем мы теперь в бинарном режиме, соответственно в форме на сайте я теперь получаю:
b'\xf2\xe5\xf1\xf2'

Передавал поле:
"тест".encode("cp1251")
reclosedev
А вопрос в чем? Как это в текст переделать?
>>> str(b'\xf2\xe5\xf1\xf2', "cp1251")
'тест'
omatic
Вопрос в передаче строки через requests в правильной кодировке. Вот пример:

сделал и передал:

text = "Привет мир"
data = {"field": text.encode("cp1251")}
r = requests.post("http://httpbin.org/post", data=data, files={'':''})

соответственно оно и передало мне в бинарном режиме, и на сайте куда передавал в форме получения текст: b'\xf2\xe5\xf1\xf2'

Если я передаю, переделав в текст:

text = "Привет мир"
data = {"field": str(text.encode("cp1251"), "cp1251")}
r = requests.post("http://httpbin.org/post", data=data, files={'':''})

то получаю в форме: тест как и в первом варианте, когда передавал просто текст без кодирование.


Но нужно что бы в форме на сайте получился текст “тест”
reclosedev
omatic
в форме получения текст: b'\xf2\xe5\xf1\xf2'
Где это смотрится? Полагаю, что получено в ответе с сайта. Так вот перекодируйте это и будет ‘тест’.

omatic
Если я передаю, переделав в текст:…
Естественно
str(text.encode("cp1251"), "cp1251") == text
omatic
reclosedev, на сайте, может я плохо обьяснил, смотрите:

Суть в том , что есть форум, в компании(хостера), мне нужно текст со своего ПК туда постить в ветку форума/новости. Форум у них на IPB старой версии, который на кодировке Windows-1251. Соответственно я делаю логин скриптом и передаю в форму создания поста, слово “тест” POST запросом, вот что я передаю то и появляется в созданной теме на форуме.

тоесть: передаю с Питона слово тест а получаю на форуме тест , соответственно я немогу там его кодировать/декодировать , передавая бинарным способом и т.п.

Вот тут то я и запутался, я неправильно передаю или просто форма форума не правильно воспринимает то что я передаю?
ZZZ
"TopicTitle" : s_cp1251.encode('cp1251'),
"TopicDesc" : 'тест'.encode('cp1251'),
"Post" : 'тест'.encode('cp1251')

http://gamejam.ru/files/codepages.png

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB