2016-07-12 5 views
-1

Hier ist mein Code:‚charmap‘ Codec kann nicht Zeichenfehler in Python kodieren, während HTML Parsing

dataFile = open('dataFile.html', 'w') 
res = requests.get('site/pm=' + str(i)) 
res.raise_for_status() 
soup = bs4.BeautifulSoup(res.text, 'html.parser') 
linkElems = soup.select('#content') 
dataFile.write(str(linkElems[0])) 

ich einen anderen Code haben, aber dies ist der Code, den ich denke, problematisch ist. Ich habe auch versucht mit:

dataFile.write(str(linkElems[0].decode('utf-8'))) 

aber das funktioniert nicht und gibt Fehler.

Mit dataFile = open('dataFile.html', 'wb') gibt mir den Fehler:

a bytes-like object is required, not 'str' 

Antwort

0

Sie Ihre Textdatei geöffnet, ohne dass eine Codierung Angabe:

dataFile = open('dataFile.html', 'w') 

Dies sagt Python die Standard-Codec für Ihr System zu verwenden. Jede Unicode-Zeichenfolge, in die Sie schreiben möchten, wird in diesen Codec codiert, und Ihr Windows-System ist nicht mit UTF-8 als Standard eingerichtet.

angeben Explizit die Codierung:

dataFile = open('dataFile.html', 'w', encoding='utf8') 

Als nächst Sie vertrauen den HTTP-Server zu wissen, was codiert, die HTML-Daten verwendet. Dies wird normalerweise nicht eingestellt, also verwenden Sie nicht response.text! Es ist nicht BeautifulSoup hier fehlerhaft, Sie sind eine Mojibake neu codieren. Die requests-Bibliothek verwendet standardmäßig die Latin-1-Codierung für text/* Inhaltstypen, wenn der Server keine explizite Codierung angibt, da der HTTP-Standard angibt, dass dies der Standardwert ist.

Siehe Encoding section of the Advanced documentation:

The only time Requests will not do this is if no explicit charset is present in the HTTP headers and the Content-Type header contains text . In this situation, RFC 2616 specifies that the default charset must be ISO-8859-1. Requests follows the specification in this case. If you require a different encoding, you can manually set the Response.encoding property, or use the raw Response.content .

Bold Hervorhebung von mir.

Pass in den response.content Rohdaten statt:

soup = bs4.BeautifulSoup(res.content, 'html.parser') 

BeautifulSoup 4 in der Regel hat eine große Aufgabe zu verwenden, um die richtige Codierung herauszufinden, beim Parsen, entweder von einem HTML <meta> Tag oder statistische Analyse der Bytes bereitgestellt . Wenn der Server eine characterset liefert, können Sie immer noch diese in BeautifulSoup aus der Antwort übergeben, aber Test zuerst, wenn requests eine Standard verwendet:

encoding = res.encoding if 'charset' in res.headers.get('content-type', '').lower() else None 
soup = bs4.BeautifulSoup(res.content, 'html.parser', encoding=encoding) 
+0

Es ist nach wie vor ein Problem. Ich bekomme seltsame Zeichen wie '' '' anstelle von einem regulären '' '. –

+0

Können diese Daten im Binärformat gespeichert werden? –

+0

@SanJeetSingh: Sie verwenden 'response.text'. Verwenden Sie nicht den Standard-Latin-1 für HTTP-Textantworten ohne Codetyp "Content-type", und das ist immer falsch. Verwenden Sie 'response.content' und überlassen Sie es BeautifulSoup, die zu verwendende Codierung herauszufinden. –

Verwandte Themen