Python-Skript, das einen UnicodeEncodeError empfängt: 'ascii' Codec kann Zeichen nicht kodieren

Ich habe ein einfaches Python-Skript, das Beiträge von reddit zieht und sie auf Twitter platziert. Leider, heute Abend begann es mit Problemen, die ich vermute, sind wegen jemandes Titel auf reddit mit einem Formatierungsproblem. Der Fehler, den ich wiederkomme, ist:

File "redditbot.py", line 82, in <module> main() File "redditbot.py", line 64, in main tweeter(post_dict, post_ids) File "redditbot.py", line 74, in tweeter print post+" "+post_dict[post]+" #python" UnicodeEncodeError: 'ascii' codec can't encode character u'\u201c' in position 34: ordinal not in range(128) 

Und hier ist mein Drehbuch:

  • Parsing verschachtelte JSON und schreibe es an CSV
  • Konvertieren Sie eine curl POST-Anforderung an Python nur mit Standard-Bibliothek
  • Eine JSON-Antwort mit Scrapy kratzen
  • Python-Abfrageobjekte sind nicht serialisierbar
  • Sanierung von Inputs an MongoDB
  • Laden einer Datei mit mehr als einer Zeile von JSON in Pythons Pandas
  •  # encoding=utf8 import praw import json import requests import tweepy import time import urllib2 import sys reload(sys) sys.setdefaultencoding('utf8') access_token = 'hidden' access_token_secret = 'hidden' consumer_key = 'hidden' consumer_secret = 'hidden' def strip_title(title): if len(title) < 75: return title else: return title[:74] + "..." def tweet_creator(subreddit_info): post_dict = {} post_ids = [] print "[bot] Getting posts from Reddit" for submission in subreddit_info.get_hot(limit=2000): post_dict[strip_title(submission.title)] = submission.url post_ids.append(submission.id) print "[bot] Generating short link using goo.gl" mini_post_dict = {} for post in post_dict: post_title = post post_link = post_dict[post] mini_post_dict[post_title] = post_link return mini_post_dict, post_ids def setup_connection_reddit(subreddit): print "[bot] setting up connection with Reddit" r = praw.Reddit('PythonReddit PyReTw' 'monitoring %s' %(subreddit)) subreddit = r.get_subreddit('python') return subreddit def duplicate_check(id): found = 0 with open('posted_posts.txt', 'r') as file: for line in file: if id in line: found = 1 return found def add_id_to_file(id): with open('posted_posts.txt', 'a') as file: file.write(str(id) + "\n") def main(): subreddit = setup_connection_reddit('python') post_dict, post_ids = tweet_creator(subreddit) tweeter(post_dict, post_ids) def tweeter(post_dict, post_ids): auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) api = tweepy.API(auth) for post, post_id in zip(post_dict, post_ids): found = duplicate_check(post_id) if found == 0: print "[bot] Posting this link on twitter" print post+" "+post_dict[post]+" #python" api.update_status(post+" "+post_dict[post]+" #python") add_id_to_file(post_id) time.sleep(3000) else: print "[bot] Already posted" if __name__ == '__main__': main() 

    Jede Hilfe wäre sehr dankbar – danke im Voraus!

    3 Solutions collect form web for “Python-Skript, das einen UnicodeEncodeError empfängt: 'ascii' Codec kann Zeichen nicht kodieren”

    Betrachten Sie dieses einfache Programm:

     print(u'\u201c' + "python") 

    Wenn Sie versuchen, auf ein Terminal zu drucken (mit einer entsprechenden Zeichencodierung), erhalten Sie

     “python 

    Wenn Sie jedoch versuchen, die Ausgabe an eine Datei umzuleiten, erhalten Sie einen UnicodeEncodeError .

     script.py > /tmp/out Traceback (most recent call last): File "/home/unutbu/pybin/script.py", line 4, in <module> print(u'\u201c' + "python") UnicodeEncodeError: 'ascii' codec can't encode character u'\u201c' in position 0: ordinal not in range(128) 

    Wenn Sie auf ein Terminal drucken, verwendet Python die Zeichencodierung des Terminals, um Unicode zu codieren. (Terminals können nur Bytes drucken, so dass Unicode codiert werden muss, um gedruckt zu werden.)

    Wenn Sie die Ausgabe an eine Datei umleiten, kann Python die Zeichencodierung nicht ermitteln, da Dateien keine deklarierte Codierung haben. Insofern kodiert Python2 implizit alle Unicode mit der ascii Codierung, bevor er in die Datei schreibt. Da u'\u201c' kann nicht ascii codiert werden, ein UnicodeEncodeError . (Nur die ersten 127 Unicode-Codepunkte können mit ascii codiert werden).

    Diese Ausgabe wird im Wissensverzeichnis im Wissensverzeichnis ausgedrückt .


    Um das Problem zu beheben, vermeiden Sie zunächst Hinzufügen von Unicode- und Byte-Strings. Dies verursacht eine implizite Umwandlung mit dem ascii-Codec in Python2 und eine Ausnahme in Python3. Um Ihren Code zukunftssicher zu machen, ist es besser, explizit zu sein. Zum Beispiel, verschlüsseln Sie post explizit vor dem Formatieren und Drucken der Bytes:

     post = post.encode('utf-8') print('{} {} #python'.format(post, post_dict[post])) 

    Sie versuchen, eine Unicode-Zeichenfolge an Ihr Terminal zu drucken (oder möglicherweise eine Datei durch IO-Umleitung), aber die von Ihrem Terminal (oder Dateisystem) verwendete Codierung ist ASCII. Weil dieses Python versucht, es von der Unicode-Darstellung in ASCII zu konvertieren, aber scheitert, weil Codepoint u'\u201c' ( ) nicht in ASCII dargestellt werden kann. Effektiv macht dein Code das:

     >>> print u'\u201c'.encode('ascii') Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode character u'\u201c' in position 0: ordinal not in range(128) 

    Sie könnten versuchen, in UTF-8 umzuwandeln:

     print (post + " " + post_dict[post] + " #python").encode('utf8') 

    Oder konvertieren nach ASCII wie folgt:

     print (post + " " + post_dict[post] + " #python").encode('ascii', 'replace') 

    Die ungültige ASCII-Zeichen ersetzen wird ? .

    Eine andere Möglichkeit, die nützlich ist, wenn Sie für Debugging-Zwecke drucken, ist es, den repr der Zeichenfolge zu drucken:

     print repr(post + " " + post_dict[post] + " #python") 

    Was so etwas ausgeben würde:

     >>> s = 'string with \u201cLEFT DOUBLE QUOTATION MARK\u201c' >>> print repr(s) u'string with \u201cLEFT DOUBLE QUOTATION MARK\u201c' 

    Das Problem besteht wahrscheinlich aus dem Mischen von Testen und Unicode-Strings auf Verkettung. Als Alternative zur Präfixierung aller String-Literale mit u , vielleicht

     from __future__ import unicode_literals 

    Behebt die Dinge für dich. Sehen Sie hier für eine tiefere Erklärung und zu entscheiden, ob es eine Option für Sie oder nicht ist.

    Python ist die beste Programmiersprache der Welt.