имитация строки, чтобы выглядеть как байт — python

#python #python-requests

Вопрос:

я пытаюсь создать какой-то код, который выводит изображения в Интернет и преобразует их в файлы в рамках проекта, который я создаю. Я столкнулся с проблемой, когда я получаю строку, которая выглядит как байты, которые вам нужно записать в файл, но мне не удается поместить ее в байт, я пытался сделать обычное «w», но это не сработает, и я пытался сделать байты(str(r.содержимое), «utf-8»), но это тоже не сработает, есть ли способ это сделать?

 import requests
x = input("enter url/path: ")
r = requests.get(x)
print(r.content)
with open("test." x.split('.')[-1], "wb") as f:
    f.write(str(r.content))
 

ошибка:

     f.write(str(r.content))
TypeError: a bytes-like object is required, not 'str'
 

Ответ №1:

Оказывается, r.contents это уже bytes объект! Из requests документации:

Вы также можете получить доступ к тексту ответа в байтах для нетекстовых запросов:

> > > > > > > > > r.содержимое b'[{«репозиторий»:{«открытые выпуски»:0,»url»:»https://github.com/…

Так что самый простой выход-просто отказаться от str() :

 f.write(r.content)
 

Теперь в комментариях вы, кажется, действительно хотите работать с реальными строками вместо байтов. Есть много веских причин хотеть этого, поэтому я не буду судить. Но requests вы тоже там рассматривали — он уже выполняет преобразование и делает его доступным как r.text !

Файл можно открыть двумя различными способами: текстовым или двоичным. Это зависит от того, есть ли у вас "b" персонаж в open вызове. Если вы опустите b это , он примет строку вместо байтообразного объекта.

 with open("test." x.split('.')[-1], "w", encoding="utf-8") as f:
    f.write(r.text)
 

Обратите внимание, что я также добавил encoding параметр, необходимый для правильного преобразования строк в байты файла.

Оказывается, str(r.content) это неправильный способ преобразования байтов в строку. Позвольте мне показать вам небольшую демонстрацию:

 >>> def whatis(x):
    print(type(x), len(x), x)

>>> whatis(r'ab')
<class 'str'> 3 ab
>>> whatis(rb'ab')
<class 'bytes'> 3 b'a\b'
>>> whatis(str(rb'ab'))
<class 'str'> 7 b'a\b'
 

Правильный способ сделать это-с помощью decode() :

 >>> whatis(rb'ab'.decode())
<class 'str'> 3 ab
 

Вы , вероятно , не хотите этого делать, хотя бы потому, что вам нужно знать, как содержимое было закодировано для передачи в качестве параметра .decode() , и r.text уже сделали то же самое для вас.

Комментарии:

1. теперь он что-то записывает в файл, но заменяет каждое » «на 2″ » (например,»»), и файл теперь не может быть загружен

2. @avi может быть, тебе стоит попробовать f.write(r.content) .

3. Весь смысл вопроса в том, чтобы взять строку, которая является r.content, в моем проекте я получаю r.content в виде строки, и мне нужно поместить ее в файл, чтобы я не мог просто написать r.content, у меня в принципе нет выбора

4. @avi Я предполагал, что str на bytes объекте он преобразует его непосредственно в строку, но я только что обнаружил, что это неправильно, и вместо этого он ведет себя repr так. В этом-то и проблема, особенно в том, почему вы получаете двойную обратную косую черту. Вместо этого вам нужно использовать r.contents.decode() , предпочтительно, параметр, указывающий кодировку исходных байтов.

5. @avi Я почти полностью переписал ответ, проверьте его и посмотрите, не решает ли он все ваши проблемы.