2016-03-17 2 views
1

Я читал документацию по запросам lib и, похоже, был поистине устаревшим или чем-то. я шаг за шагом идти, пытаясь все примеры, показанные здесь и столкнулись с проблемой, когда я попытался запустить следующий фрагмент:Содержимое бинарного ответа, запросы lib

import requests 
from PIL import Image 
from StringIO import StringIO 

response = requests.get('http://www.github.com') 
i = Image.open(StringIO(response.content)) 

Этот кусок от официальной документации. Первой ошибкой, которую я получил, был ImportError: нет модуля с именем StringIO

Хорошо, тогда я узнал, что этот модуль больше не существует, и для того, чтобы импортировать StringIO, нужно написать from io import StringIO. Я это сделал. Попробовал снова запустить код, и на этот раз он с ошибкой «TypeError: initial_value должен быть str или None, а не байтами». Что я сделал неправильно? Я не следую ... Все, что я сделал, это попробовать запустить код из официального документа ... Я не знаю.

EDITED: И да ... для использования PIL необходимо установить подушку.

+0

Это может помочь [http://stackoverflow.com/questions/31064981/python3-error-initial-value-must-be-str-or-none] –

+0

Есть некоторые основные различия между Python2.x и Python3.x (особенно в отношении обработки строк). Это является причиной * некоторых * ваших проблем. Где вы получаете 'response.get ...', и почему вы думаете, что это то же самое, что и модуль' request', я не знаю. – jDo

+0

@jDo oops, извините, это просто опечатка. В действительности это должно быть request.get (....). – Albert

ответ

2

от того, что вы говорите, вы используете python3 (поскольку пакет StringIO был переименован io в python3, а не python2), а ваш пример - python2 (по понятным причинам).

Так что для вашего вопроса:

"TypeError:initial_value must be str or None, not bytes". 

Что это означает, что в:

response = requests.get('http://www.github.com') 

вы либо получаете None или ответ в bytes для response.content. Учитывая, что ваш запрос работал, и вы можете получить доступ к response.content, это, скорее всего, будет в bytes.

Поскольку библиотека requests работает на довольно низком уровне, а все входящие данные и сокеты (включая сокет HTTP) являются обычными двоичными (т.е. не интерпретируемыми), чтобы иметь возможность использовать вывод в строковых функциях, которые вам нужны превратить его во что-то.

В Python3 str старый unicode от python2 и bytes близко к старому str из python2. Таким образом, вы бы нужно преобразовать байт в строку кормить StringIO:

i = Image.open(StringIO(response.content.decode('utf-8'))) 

, например. Но тогда я ожидаю, что Image.open() будет кричать на вас, что он не знает, что wtf предполагается использовать с буфером Unicode, все, что он действительно хочет, это байтовый массив!

Но поскольку Image.open() на самом деле ожидает поток байтов, а не поток юникода, что вы должны делать на самом деле использовать BytesIO вместо StringIO:

from io import BytesIO 
i = Image.open(BytesIO(response.content)) 

Наконец, вы сладкий, чтобы привести пример, но это не тот, который будет работать, поскольку вы даете ссылку на HTML-страницу вместо изображения.

НТН

+0

haha ​​спасибо! Довольно ясное объяснение. Теперь я попытаюсь сделать то, что вы предложили. – Albert

+0

странная вещь на самом деле заключается в том, что здесь https://media.readthedocs.org/pdf/requests/master/requests.pdf они делают примерно то же самое, они также дают ссылку на HTML-страницу. Но похоже, что это должен как-то работать ... Мне очень интересно! – Albert

+0

Я уверен, что учебник написан с учетом python2, тогда как вы работаете с python3. Это не значит, что учебник не имеет значения, но вам нужно сначала конвертируйте примеры. Возможно, вы захотите проверить свои скрипты с помощью инструмента «2to3», который автоматически преобразует большинство f проблемный код python2 в python3. – zmo

0

Это хорошая идея, чтобы на самом деле принести изображение из Интернета, если один хочет, чтобы разобрать изображения: D (в отличие от выборки индексной страницы на github.com)

import requests 
from PIL import Image 
from StringIO import StringIO 

url = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/46/Venn0110.svg/576px-Venn0110.svg.png" 
response = requests.get(url) 
i = Image.open(StringIO(response.content)) 

Например, вы пытаетесь использовать внешне отличается от того, что вы разместили здесь:

3.3.4 Binary Response Content 
You can also access the response body as bytes, for non-text requests: 
>>> r.content 
b'[{"repository":{"open_issues":0,"url":"https://github.com/... 
The gzip and deflate transfer-encodings are automatically decoded for you. 
For example, to create an image from binary data returned by a request, you can use the following code: 
>>> from PIL import Image 
>>> from StringIO import StringIO 
>>> i = Image.open(StringIO(r.content)) 

https://github.com/... < - эти три точки (эллипсы) показывают, что U RL в этом примере сокращен.

источник: Requests Documentation Release 2.9.1

+1

ха-ха, ты прав ... Не могу поверить, что я спросил, что. О, я не должен задавать вопросы, когда я не трезвый: D – Albert

Смежные вопросы