546 Stimmen

UnicodeEncodeError: Der Codec 'charmap' kann Zeichen nicht encoden

Ich versuche, eine Website zu scrapen, aber es gibt mir einen Fehler.

Ich benutze den folgenden Code:

import urllib.request
from bs4 import BeautifulSoup

get = urllib.request.urlopen("https://www.website.com/")
html = get.read()

soup = BeautifulSoup(html)

Und ich bekomme den folgenden Fehler:

File "C:\Python34\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 70924-70950: character maps to 

Was kann ich tun, um das zu beheben?

15voto

Pardhu Gopalam Punkte 179

Sogar ich hatte dasselbe Problem mit der Codierung, die auftritt, wenn Sie versuchen, es zu drucken, zu lesen/schreiben oder zu öffnen. Wie oben von anderen erwähnt, hilft es, .encoding="utf-8" hinzuzufügen, wenn Sie versuchen, es zu drucken.

soup.encode("utf-8")

Wenn Sie versuchen, gescrapte Daten zu öffnen und sie vielleicht in eine Datei schreiben möchten, öffnen Sie die Datei mit (......,encoding="utf-8")

with open(filename_csv , 'w', newline='',encoding="utf-8") as csv_file:

5voto

Pseudo Sudo Punkte 1412

Für diejenigen, die immer noch diesen Fehler bekommen, wird durch Hinzufügen von encode("utf-8") zu soup dies ebenfalls behoben.

soup = BeautifulSoup(html_doc, 'html.parser').encode("utf-8")
print(soup)

5voto

tripleee Punkte 155951

Es gibt mehrere Aspekte dieses Problems. Die grundlegende Frage ist, in welchem Zeichensatz Sie ausgeben möchten. Möglicherweise müssen Sie auch den Eingabezeichensatz herausfinden.

Das Drucken (entweder mit print oder write) in eine Datei mit einem expliziten encoding="..." wandelt die interne Unicode-Repräsentation von Python in diese Codierung um. Wenn die Ausgabe Zeichen enthält, die von dieser Codierung nicht unterstützt werden, erhalten Sie einen UnicodeEncodeError. Sie können z.B. kein Russisch oder Chinesisch oder Indisch oder Hebräisch oder Arabisch oder Emoji oder ... oder irgendetwas außer einem eingeschränkten Satz von etwa 200+ westlichen Zeichen in eine Datei schreiben, deren Codierung "cp1252" ist, da dieser begrenzte 8-Bit-Zeichensatz keine Möglichkeit hat, diese Zeichen darzustellen.

Grundsätzlich tritt dasselbe Problem bei jedem 8-Bit-Zeichensatz auf, einschließlich fast aller veralteten Windows-Zeichensätze (437, 850, 1250, 1251 usw.), obwohl einige von ihnen zusätzlich zu oder anstelle von Englisch einige weitere Skriptsprachen unterstützen (1251 unterstützt beispielsweise Kyrillisch, sodass Sie Russisch, Ukrainisch, Serbisch, Bulgarisch usw. schreiben können). Eine 8-Bit-Codierung hat nur maximal 256 Zeichencodes und keine Möglichkeit, ein Zeichen darzustellen, das nicht darunter fällt.

Vielleicht wäre es jetzt eine gute Zeit, Joel Spolskys Das absolute Minimum, das jeder Softwareentwickler unbedingt über Unicode und Zeichencodierungen wissen muss (Keine Ausreden!)

Auf Plattformen, auf denen das Terminal Unicode nicht drucken kann (heutzutage nur noch Windows, obwohl dieses Problem auch auf anderen Plattformen im letzten Jahrtausend weit verbreitet war), kann der Versuch, Unicode-Strings mit print zu drucken, ebenfalls diesen Fehler verursachen oder zu Mojibake führen. Wenn Sie beispielsweise etwas wie Héllö anstelle von Héllö sehen, liegt hier Ihr Problem.

Kurz gesagt, Sie müssen also wissen:

  • Was ist der Zeichensatz der Seite, die Sie gescraped haben, oder der Daten, die Sie erhalten haben? Wurde korrekt gescraped? Hat der Ursprungskontakt seine Codierung korrekt angegeben oder sind Sie anderweitig in der Lage, diese Informationen zu erhalten (oder zu erraten)? Einige Websites geben fälschlicherweise einen anderen Zeichensatz an, als die Seite tatsächlich enthält, einige Websites haben die Verbindung zwischen dem Webserver und einer Datenbank falsch konfiguriert. Siehe z.B. Scrapen mit korrekter Zeichencodierung (Python-Anforderungen + Beautifulsoup) für ein detaillierteres Beispiel mit einigen Lösungen.

  • Welchen Zeichensatz möchten Sie schreiben? Wenn Sie auf den Bildschirm drucken, ist Ihr Terminal korrekt konfiguriert und Ihr Python-Interpreter identisch konfiguriert? Eventuell auch siehe Wie man UTF-8 in der Windows-Konsole anzeigt

Wenn Sie hier sind, ist die Antwort auf eine dieser Fragen wahrscheinlich nicht "UTF-8". Diese Codierung wird zunehmend auch für Webseiten verwendet, obwohl der frühere Standard ISO-8859-1 (auch Latin-1 genannt) war und vor kurzem noch Windows Codepage 1252.

In Zukunft möchten Sie im Grunde genommen, dass alle Ihre textuellen Daten Unicode sind, außergewöhnlich sind einige Randfälle. Im Allgemeinen bedeutet das UTF-8, obwohl auf Windows (oder wenn Sie Java-Kompatibilität benötigen) auch UTF-16 halbwegs praktikabel ist, wenn auch etwas umständlich. (Es gibt mehrere andere Unicode-Serialisierungsformate, die in spezialisierten Fällen nützlich sein können. UTF-32 ist technisch trivial, benötigt jedoch deutlich mehr Speicher; UTF-7 wird in einigen Netzwerkprotokollen verwendet, bei denen 7-Bit-ASCII für den Transport erforderlich ist.) Eventuell auch siehe https://utf8everywhere.org/

Natürlich müssen Sie, wenn Sie in eine Datei drucken, diese Datei auch mit einem Tool untersuchen, das sie korrekt anzeigen kann. Ein häufiger Pilotenfehler ist, die Datei mit einem Tool zu öffnen, das nur die derzeit ausgewählte Systemcodierung anzeigt oder das die Codierung zu erraten versucht, aber falsch liegt. Bei der Anzeige von UTF-8-Text mit der Windows-Codepage 1252 würde beispielsweise Héllö als Héllö dargestellt.

Wenn die Codierung von Zeichendaten unbekannt ist, gibt es keine einfache Möglichkeit, sie automatisch festzustellen. Wenn Sie wissen, was der Text darstellen soll, können Sie dies vielleicht ableiten, aber dies ist in der Regel ein manueller Prozess mit einigen Schätzungen (Automatische Tools wie chardet und ftfy können helfen, machen aber manchmal Fehler.)

Um festzustellen, welche Codierung Sie betrachten, kann es hilfreich sein, wenn Sie die einzelnen Bytes in einem Zeichen identifizieren können, der nicht korrekt angezeigt wird. Wenn Sie z.B. H\x8ell\x9a betrachten, es aber als Héllö erwarten, können Sie die Bytes in einer Übersetzungstabelle nachschlagen. Ich habe eine solche Tabelle unter https://tripleee.github.io/8bit veröffentlicht, wo Sie sehen können, dass es sich in diesem Beispiel wahrscheinlich um einen der veralteten Mac 8-Bit-Zeichensätze handelt; mit weiteren Datenpunkten können Sie es vielleicht auf nur einen von ihnen eingrenzen (und wenn nicht, tut es in der Praxis jeder von ihnen, da alle Codepunkte, die für Sie relevant sind, auf die gleichen Unicode-Zeichen abbilden).

Python 3 auf den meisten Plattformen verwendet standardmäßig für alle Eingaben und Ausgaben UTF-8, auf Windows ist dies jedoch in der Regel nicht der Fall. Dann wird stattdessen standardmäßig die Standardcodierung des Systems verwendet (in einigen Microsoft-Dokumentationen immer noch irreführenderweise als "ANSI-Codepage" bezeichnet), die von einer Reihe von Faktoren abhängt. Auf westlichen Systemen ist die Standardcodierung Out-of-the-box Windows Codepage 1252.

Wenn Sie auf Windows UTF-8 in eine Textdatei schreiben, geben Sie möglicherweise encoding="utf-8-sig" an, das eine BOM-Sequenz am Anfang der Datei hinzufügt. Dies ist streng genommen nicht notwendig oder korrekt, aber einige Windows-Tools benötigen es, um die Codierung korrekt zu erkennen.

Mehrere der früheren Antworten hier schlagen vor, blind eine Codierung anzuwenden, aber hoffentlich hilft Ihnen das zu verstehen, dass dies im Allgemeinen nicht der richtige Ansatz ist, und wie Sie herausfinden - anstatt zu raten - welche Codierung zu verwenden ist.

5voto

Smart Manoj Punkte 4319

Von Python 3.7 an,
Setzen Sie die Umgebungsvariable PYTHONUTF8 auf 1

Das folgende Skript enthält auch andere nützliche Variablen, die Systemumgebungsvariablen setzen.

setx /m PYTHONUTF8 1
setx PATHEXT "%PATHEXT%;.PY" ; In CMD kann die Python-Datei ohne Erweiterung ausgeführt werden.
setx /m PY_PYTHON 3.10 ; um die Standard-Python-Version für py festzulegen

Quelle

3voto

Shubham rawat Punkte 69

Ich hatte den gleichen Fehler, also habe ich (encoding="utf-8") verwendet und dadurch den Fehler behoben. Dies passiert meistens, wenn wir ein nicht identifiziertes Symbol oder Muster in Textdaten haben, das unser Encoder nicht versteht.

with open("text.txt", "w", encoding='utf-8') as f:
     f.write(data)

Dies wird dein Problem lösen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X