2016-07-24 1 views
0

Я использую python 3.5.2 и scrapy 1.1.1.python 3.5: "TypeError: memoryview: требуется объект с байтом, а не 'str'"

Существует ошибка при выполнении кода ниже:

#-*- coding:utf-8-*- 

import random 
import base64 


class ProxyMiddleware(object): 
    def process_request(self, request, spider): 
     proxy = random.choice(PROXIES) 
     if proxy['user_pass'] is not None: 
      request.meta['proxy'] = "http://%s" % proxy['ip_port'] 
      encoded_user_pass = base64.encodebytes(proxy['user_pass']) 
      request.headers['Proxy-Authorization'] = 'Basic ' + encoded_user_pass 
      print("ok!" + proxy['ip_port']) 
     else: 
      print("fail!" + proxy['ip_port']) 
      request.meta['proxy'] = "http://%s" % proxy['ip_port'] 

ошибка:

File "C:\Users\dell\AppData\Local\Programs\Python\Python35\lib\base64.py", line 518, in _input_type_check 
    m = memoryview(s) 
    TypeError: memoryview: a bytes-like object is required, not 'str' 

Я думаю, что ошибка связана с этим предложением:

encoded_user_pass = base64.encodebytes(proxy['user_pass']) 

Но дон Не знаю, как его решить.
Некоторая помощь пожалуйста,
заранее!

Edit:

encoded_user_pass = base64.encodebytes(proxy['user_pass']) 

было изменено на

encoded_user_pass = base64.encodebytes(proxy['user_pass'].encode()) 

есть другая ошибка:

request.headers['Proxy-Authorization'] = 'Basic ' + encoded_user_pass 
TypeError: Can't convert 'bytes' object to str implicitly 

что я должен делать?

+0

Просто FYI base64 кодирования пароль небезопасен и почти ничего не делает с точки зрения безопасности. Вы должны изучить солевое хеширование для более безопасного способа сделать это; посмотрите этот вопрос: http://stackoverflow.com/questions/9594125/salt-and-hash-a-password-in-python – Granitosaurus

+0

@Granitosaurus Спасибо, я попробую его позже. Теперь есть еще одна ошибка, см. мое редактирование ,благодаря. – zwl1619

ответ

1

Функция base64.encodebytes() ожидает байт значения, и кажется, что вы предоставляете это строка.

Чтобы исправить это, вы можете просто кодировать строковое значение (шифровать() функция превращает ваш объект строки в объект байт):

base64.encodebytes('foo'.encode()) 

или в вашем случае:

encoded_user_pass = base64.encodebytes(proxy['user_pass'].encode()) 
+0

Что касается вашего редактирования: здесь ваша ошибка означает, что одно значение является 'string', другое -' bytes', и когда вы пытаетесь добавить их, python немного запутывается. Вы должны либо преобразовать оба байта в 'str.encode()', либо преобразовать оба в строку с 'bytes.decode()'. Вы можете просто исправить это с помощью 'b'Basic '+ encoded_user_pass' в этом конкретном случае. – Granitosaurus

1

Как следует из названия, base64.encodebytes кодирует байт, а не строки. Как указано в документации, для этого требуется bytes-like object (как и сообщение об ошибке).

Ваше значение proxy['user_pass'] является строкой. Для того чтобы преобразовать это в байтах, вызовите str.encode:

encoded_user_pass = base64.encodebytes(proxy['user_pass'].encode())