UnicodeEncodeError: Der Codec 'charmap' kann keine Zeichen codieren

204

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

Ich verwende den folgenden Code:

import urllib.request
from bs4 import BeautifulSoup

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

soup = BeautifulSoup(html)

print(soup)

Und ich bekomme 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 <undefined>

Was kann ich tun, um dies zu beheben?

SstrykerR
quelle

Antworten:

255

UnicodeEncodeErrorBeim Speichern von abgekratzten Webinhalten in einer Datei wurde das Gleiche erreicht . Um das Problem zu beheben, habe ich diesen Code ersetzt:

with open(fname, "w") as f:
    f.write(html)

mit diesem:

import io
with io.open(fname, "w", encoding="utf-8") as f:
    f.write(html)

Durch iodie Verwendung erhalten Sie Abwärtskompatibilität mit Python 2.

Wenn Sie nur Python 3 unterstützen müssen, können Sie openstattdessen die integrierte Funktion verwenden:

with open(fname, "w", encoding="utf-8") as f:
    f.write(html)
twasbrillig
quelle
6
In Mac (Python 3) funktioniert perfekt mit nur Öffnen ohne Codierung, aber in Windows (W10, Python3) ist keine Option. Funktioniert einfach so, mit encoding = "utf-8" param.
xtornasol512
3
Danke dir. Es hat bei mir funktioniert, ich habe mit XML-Dateien gearbeitet und das Ergebnis von xml.toprettyxml () in eine neue Datei geschrieben
Luis Cabrera Benito
1
Dies sollte die akzeptierte Antwort sein, da schließlich eine Zeichenfolge in die Ausgabe geschrieben wird und keine Zeichenfolgendarstellung von Bytes.
Shirkan
OP forderte an, die Datei zu lesen, jedoch nicht zu schreiben. Das Problem scheint konsolenbezogen zu sein.
NaturalBornCamper
187

Ich habe es durch Hinzufügen .encode("utf-8")zu behoben soup.

Das heißt das print(soup)wird print(soup.encode("utf-8")).

SstrykerR
quelle
3
Codieren Sie die Zeichencodierung Ihrer Umgebung (z. B. Konsole) in Ihrem Skript nicht fest, sondern drucken Sie stattdessen Unicode direkt aus
jfs
Dies ist nur das Drucken des Repr eines bytesObjekts, das als Durcheinander von \xSequenzen gedruckt wird, wenn viel UTF-8-codierter Text vorhanden ist. Ich empfehle die Verwendung win_unicode_console, wie @JFSebastian vorschlägt.
Eryk Sun
2
Ich habe die obige Lösung verwendet, aber es treten immer noch Probleme auf: Klasse MyStreamListener (tweepy.StreamListener): def on_status (self, status): print (str (status.encode ("utf-8"))) UnicodeEncodeError: 'charmap' codec can ' t codiere das Zeichen '\ u2019' in Position 87: Das Zeichen wird <undefined> zugeordnet
Vivek
2
Dadurch wird es b'\x02x\xc2\xa9'stattdessen
ausgedruckt
1
print(soup.encode("utf-8"))arbeitete für mich, aber vorher musste ich auch hinzufügenwith open("f_name", encoding="utf-8") as f: soup = BeautifulSoup(f, "html.parser")
TheWalkingData
44

In Python 3.7 und unter Windows 10 hat dies funktioniert (ich bin nicht sicher, ob es auf anderen Plattformen und / oder anderen Versionen von Python funktioniert).

Diese Zeile ersetzen:

with open('filename', 'w') as f:

Mit diesem:

with open('filename', 'w', encoding='utf-8') as f:

Der Grund, warum es funktioniert, liegt darin, dass die Codierung bei Verwendung der Datei in UTF-8 geändert wird, sodass Zeichen in UTF-8 in Text konvertiert werden können, anstatt einen Fehler zurückzugeben, wenn ein UTF-8-Zeichen auftritt nicht durch die aktuelle Codierung unterstützt.

Sabbir Ahmed
quelle
1
print (suppe) return \ xd0 \ xbf \ xd0 \ xbe \ xd0 \ xb6 \ xd0 \ xb0 \ xd0 \ xbb \ xd1 \ x83 \ xd0 \ xb9 \ xd
Kaffee inTime
12

Beim Speichern der Antwort von get request wurde in Fenster 10 derselbe Fehler in Python 3.7 ausgelöst. Die von der URL empfangene Antwort lautete UTF-8. Es wird daher immer empfohlen, die Codierung zu überprüfen, damit dieselbe übergeben werden kann, um solche trivialen Probleme zu vermeiden da es wirklich viel Zeit in der Produktion tötet

import requests
resp = requests.get('https://en.wikipedia.org/wiki/NIFTY_50')
print(resp.encoding)
with open ('NiftyList.txt', 'w') as f:
    f.write(resp.text)

Als ich mit dem Befehl open encoding = "utf-8" hinzufügte, wurde die Datei mit der richtigen Antwort gespeichert

with open ('NiftyList.txt', 'w', encoding="utf-8") as f:
    f.write(resp.text)
Abhishek Jain
quelle
10

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

oup.encode ("utf-8")

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

mit open (Dateiname_csv, 'w', newline = '', encoding = "utf-8") als csv_file:

Pardhu Gopalam
quelle
6

Wenn Sie diesen Fehler weiterhin erhalten, wird dies durch Hinzufügen encode("utf-8")zu soupebenfalls behoben.

soup = BeautifulSoup(html_doc, 'html.parser').encode("utf-8")
print(soup)
Pseudo Sudo
quelle
2
soupist kein BeautifulSoupObjekt mehr, nachdem Sie dies getan haben, so dass es nicht manipuliert oder durchsucht werden kann
NaturalBornCamper