2013-06-13 3 views
1

Я пытаюсь разобрать произвольных веб-страниц с requests и BeautifulSoup библиотек с этим кодом:просит библиотека сбой на Python 2 и Python 3 с

try: 
    response = requests.get(url) 
except Exception as error: 
    return False 

if response.encoding == None: 
    soup = bs4.BeautifulSoup(response.text) # This is line 809 
else: 
    soup = bs4.BeautifulSoup(response.text, from_encoding=response.encoding) 

На большинстве веб-страниц это работает отлично. Однако, на некоторых произвольных страниц (< 1%) Я получаю эту аварию:

Traceback (most recent call last): 
    File "/home/dotancohen/code/parser.py", line 155, in has_css 
    soup = bs4.BeautifulSoup(response.text) 
    File "/usr/lib/python3/dist-packages/requests/models.py", line 809, in text 
    content = str(self.content, encoding, errors='replace') 
    TypeError: str() argument 2 must be str, not None 

Для справки, это метод Релевент библиотеки запросов:

@property 
def text(self): 
    """Content of the response, in unicode. 

    if Response.encoding is None and chardet module is available, encoding 
    will be guessed. 
    """ 

    # Try charset from content-type 
    content = None 
    encoding = self.encoding 

    # Fallback to auto-detected encoding. 
    if self.encoding is None: 
     if chardet is not None: 
      encoding = chardet.detect(self.content)['encoding'] 

    # Decode unicode from given encoding. 
    try: 
     content = str(self.content, encoding, errors='replace') # This is line 809 
    except LookupError: 
     # A LookupError is raised if the encoding was not found which could 
     # indicate a misspelling or similar mistake. 
     # 
     # So we try blindly encoding. 
     content = str(self.content, errors='replace') 

    return content 

Как можно видеть, я не передавая в кодировке, когда эта ошибка возникает. Как я неправильно использую библиотеку и что я могу сделать, чтобы предотвратить эту ошибку? Это на Python 3.2.3, но я также могу получить те же результаты с Python 2.

ответ

1

Это означает, что сервер не отправил кодировку для содержимого в заголовках, а библиотека chardet также не была в состоянии для определения кодировки содержимого. Вы на самом деле намеренно проверяете отсутствие кодировки; зачем пытаться получить декодированный текст, если нет кодировки?

Вы можете попробовать оставить декодирование до BeautifulSoup парсер:

if response.encoding is None: 
    soup = bs4.BeautifulSoup(response.content) 

и нет нет необходимости передавать в кодировке в BeautifulSoup, так как если .text не подведет, вы используете Unicode и BeautifulSoup в любом случае будет игнорировать параметр кодирования:

else: 
    soup = bs4.BeautifulSoup(response.text) 
+0

Thank you Martijn! Используя этот код, я проанализировал около 1000 URL-адресов без проблем, поэтому похоже, что это решение! – dotancohen

+0

'.text' терпит неудачу, поскольку на сервере не было никакой кодировки, и у вас нет' chardet' (который поставляется * с * 'запросами', в комплекте) или' chardet' не смог определить кодировку. Последний должен сделать образованную догадку, и иногда это терпит неудачу. –

+0

Вижу. Большое вам спасибо, ваше понимание очень ценится! – dotancohen