Python запросы, CSV, Sha256 и BOM
Я собираю набор CSV для спортсменов, используя Requests и Python 2.7.
Эти файлы создаются сервером отчетов MSFT и называются iso-8859-1, сообщает Requests.
Поскольку я имею дело с тысячами каждую ночь, я хочу вычислить файлы и сравнить с предыдущим хешем для спортсмена. Если хеш совпадает, я не буду беспокоиться о сохранении файла на диск. Эти файлы невелики - самый большой - около 6 КБ, поэтому нет проблем с потоковой передачей.
Однако sha256 не работает из-за надоедливой спецификации с этими файлами. Я посмотрел на 10 различных "решений" здесь и не могу найти одно, которое вытянет спецификацию через decode.encode, чтобы я мог сделать свой sha256.
Один из обходных путей, к которому мне, возможно, придется вернуться, заключается в том, что я могу записать файл на диск, а затем скопировать его туда. Но это кажется действительно плохой формой.
Если я смогу удалить спецификацию в начале, у меня будет процесс, который работает с sha256 и избавит меня от работы с лишними файлами.
Я думаю, что проблема может заключаться в том, что я якобы пытаюсь выполнить строковые операции над тем, что является файловым объектом. Но так как объект все еще a u"/... hex stream, я думал, что эти операции будут работать...
Вот подробности:
>>> r = requests.get('http://66.73.188.164/ReportServer?%2fCPTC%2fWomens1stHalfDetail&Team=&player=17424&rs:Format=CSV')
>>> r.status_code
200
>>> r.raw
<requests.packages.urllib3.response.HTTPResponse object at 0x18afb70>
>>> r.encoding
'ISO-8859-1'
>>> print r.headers['content-type']
text/plain
>>> r.text[0]
u'\xff'
Первая попытка преобразования не удается декодировать с использованием указанного типа кодировки!
>>> z = r.text
>>> z.decode('iso-8859-1').encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
И действительно, "тип" z теперь отличается от ожидаемого, возможно, из-за sys (mac; utf8)?
>>> type(z)
<type 'unicode'>
>>> z[0]
u'\xff'
>>> z[0:5]
u'\xff\xfem\x00a'
Различные попытки декодировать и кодировать потерпели неудачу; Вот одна из многих таких попыток.
>>> z.decode('utf-8-sig').encode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/encodings/utf_8_sig.py", line 22, in decode
(output, consumed) = codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
Я уверен, что ответ однострочник; Я просто не вижу этого. Любое руководство наиболее ценится.
2 ответа
Может быть, вы можете попробовать опустить BOM, кодируя только остальную часть файла, чтобы получить sha256? Как в:
z = r.text[2:]
z.decode ...
Та же самая логика должна была бы применяться к хэшам файлов, уже сохраненных на диске, но это не должно быть проблемой.
Вы должны просто использовать r.content
например,
r.content.decode('utf8')
В качестве альтернативы вы также можете переопределить r.encoding
дела
r.encoding = 'utf8'
И тогда вы можете использовать r.text
не волнуясь