Исправить ошибку кодирования с помощью цикла в BeautifulSoup4?

Это последующая работа по фокусировке на конкретных результатах при очистке Twitter с помощью Python и Beautiful Soup 4? и использование Python для склеивания вложенных Div и Spans в Twitter? ,

Я не использую API-интерфейс Twitter, потому что он не смотрит на твиты хэштегом так далеко.

EDIT: ошибка, описанная здесь, встречается только в Windows 7. Код работает в Linux, как сообщается bernie, см. Комментарий ниже, и я могу запустить его без ошибок кодирования в OSX 10.10.2.

Ошибка кодирования возникает, когда я пытаюсь закодировать код, который очищает содержимое твита.

Этот первый фрагмент сбрасывает только первый твит и получает все в тегах <p> , как и предполагалось.

 amessagetext = soup('p', {'class': 'TweetTextSize js-tweet-text tweet-text'}) amessage = amessagetext[0] 

Однако, когда я пытаюсь использовать цикл для очистки всех твитов, используя этот второй фрагмент,

 messagetexts = soup('p', {'class': 'TweetTextSize js-tweet-text tweet-text'}) messages = [messagetext for messagetext in messagetexts] 

Я получаю эту известную cp437.py кодирования cp437.py .

 File "C:\Anaconda3\lib\encodings\cp437.py", line 19, in encode return codecs.charmap_encode(input,self.errors,encoding_map)[0] UnicodeEncodeError: 'charmap' codec can't encode character '\u2014' in position 4052: character maps to <undefined> 

Так почему же код для первого твита успешно очищается, но множественные твиты вызывают проблемы с кодировкой? Это просто потому, что в первом твиттере нет проблемных персонажей? Я пробовал соскабливать первый твит на нескольких разных результатах поиска, поэтому я не уверен, что это причина.

Как я могу это исправить? Я прочитал несколько сообщений и разделов книги об этом, и я понимаю, почему это происходит, но я не уверен, как исправить его в коде BeautifulSoup.

Вот полный код для справки.

 from bs4 import BeautifulSoup import requests import sys import csv #Will be exporting to csv url = 'https://twitter.com/search?q=%23bangkokbombing%20since%3A2015-08-10%20until%3A2015-09-30&src=typd&lang=en' headers = {'User-Agent': 'Mozilla/5.0'} # (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'} r = requests.get(url, headers=headers) data = r.text.encode('utf-8') soup = BeautifulSoup(data, "html.parser") names = soup('strong', {'class': 'fullname js-action-profile-name show-popup-with-id'}) usernames = [name.contents[0] for name in names] handles = soup('span', {'class': 'username js-action-profile-name'}) userhandles = [handle.contents[1].contents[0] for handle in handles] athandles = [('@')+abhandle for abhandle in userhandles] links = soup('a', {'class': 'tweet-timestamp js-permalink js-nav js-tooltip'}) urls = [link["href"] for link in links] fullurls = [('http://www.twitter.com')+permalink for permalink in urls] timestamps = soup('a', {'class': 'tweet-timestamp js-permalink js-nav js-tooltip'}) datetime = [timestamp["title"] for timestamp in timestamps] messagetexts = soup('p', {'class': 'TweetTextSize js-tweet-text tweet-text'}) messages = [messagetext for messagetext in messagetexts] amessagetext = soup('p', {'class': 'TweetTextSize js-tweet-text tweet-text'}) amessage = amessagetext[0] retweets = soup('button', {'class': 'ProfileTweet-actionButtonUndo js-actionButton js-actionRetweet'}) retweetcounts = [retweet.contents[3].contents[1].contents[1].string for retweet in retweets] favorites = soup('button', {'class': 'ProfileTweet-actionButtonUndo u-linkClean js-actionButton js-actionFavorite'}) favcounts = [favorite.contents[3].contents[1].contents[1].string for favorite in favorites] print (usernames, "\n", "\n", athandles, "\n", "\n", fullurls, "\n", "\n", datetime, "\n", "\n",retweetcounts, "\n", "\n", favcounts, "\n", "\n", amessage, "\n", "\n", messages) 

Я решил это к собственному удовлетворению, исключив инструкции печати, которые я использовал для проверки ошибок, и указав кодировку для HTML-файла, который был очищен, и выходного файла csv, добавив encoding="utf-8" в оба with open командами.

 from bs4 import BeautifulSoup import requests import sys import csv import re from datetime import datetime from pytz import timezone url = input("Enter the name of the file to be scraped:") with open(url, encoding="utf-8") as infile: soup = BeautifulSoup(infile, "html.parser") #url = 'https://twitter.com/search?q=%23bangkokbombing%20since%3A2015-08-10%20until%3A2015-09-30&src=typd&lang=en' #headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'} #r = requests.get(url, headers=headers) #data = r.text.encode('utf-8') #soup = BeautifulSoup(data, "html.parser") names = soup('strong', {'class': 'fullname js-action-profile-name show-popup-with-id'}) usernames = [name.contents for name in names] handles = soup('span', {'class': 'username js-action-profile-name'}) userhandles = [handle.contents[1].contents[0] for handle in handles] athandles = [('@')+abhandle for abhandle in userhandles] links = soup('a', {'class': 'tweet-timestamp js-permalink js-nav js-tooltip'}) urls = [link["href"] for link in links] fullurls = [permalink for permalink in urls] timestamps = soup('a', {'class': 'tweet-timestamp js-permalink js-nav js-tooltip'}) datetime = [timestamp["title"] for timestamp in timestamps] messagetexts = soup('p', {'class': 'TweetTextSize js-tweet-text tweet-text'}) messages = [messagetext for messagetext in messagetexts] retweets = soup('button', {'class': 'ProfileTweet-actionButtonUndo js-actionButton js-actionRetweet'}) retweetcounts = [retweet.contents[3].contents[1].contents[1].string for retweet in retweets] favorites = soup('button', {'class': 'ProfileTweet-actionButtonUndo u-linkClean js-actionButton js-actionFavorite'}) favcounts = [favorite.contents[3].contents[1].contents[1].string for favorite in favorites] images = soup('div', {'class': 'content'}) imagelinks = [src.contents[5].img if len(src.contents) > 5 else "No image" for src in images] #print (usernames, "\n", "\n", athandles, "\n", "\n", fullurls, "\n", "\n", datetime, "\n", "\n",retweetcounts, "\n", "\n", favcounts, "\n", "\n", messages, "\n", "\n", imagelinks) rows = zip(usernames,athandles,fullurls,datetime,retweetcounts,favcounts,messages,imagelinks) rownew = list(rows) #print (rownew) newfile = input("Enter a filename for the table:") + ".csv" with open(newfile, 'w', encoding='utf-8') as f: writer = csv.writer(f, delimiter=",") writer.writerow(['Usernames', 'Handles', 'Urls', 'Timestamp', 'Retweets', 'Favorites', 'Message', 'Image Link']) for row in rownew: writer.writerow(row)