ubuntuusers.de

Lesen aus html-Datei in Python-Programm

Status: Gelöst | Ubuntu-Version: Ubuntu 18.10 (Cosmic Cuttlefish)
Antworten |

caiusjuliuscaesar

Anmeldungsdatum:
20. Januar 2009

Beiträge: 307

Hallo,

ich lese aus einer html-Datei in ein Python-Programm ein und bekomme dann folgendes typische Problem:

1
au\xc3\x9fen

statt

1
außen

Wie kann ich die eingelesenen Strings so umwandeln, daß ein Python-print den String korrekt ausgibt? Ich vermute, ich muß die Strings von utf8 in unicode umwandeln.

Das folgende tut es aber nicht (vermutlich Python 2):

1
unicode(meinString).encode('utf8')

Wer weiß Rat?

Gruß und danke, CJC

Axel-Erfurt

Anmeldungsdatum:
18. Mai 2016

Beiträge: 1347

etwa so

1
2
3
4
5
6
7
8
9
import sys


t = "au\xc3\x9fen"

if int(sys.version[0]) < 3:
    print(t)
else:
    print(t.encode('latin-1').decode('utf-8'))

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

Du musst das Encoding der Datei kennen und es beim beim Öffnen angeben - mit Python3 also z.B. so:

1
2
3
4
#!/usr/bin/env python3
with open('myhtml.html', encoding='iso8859-15') as f:
    for line in f:
        print(line)

Unter Python >=2.6 kannst stattdessen io.open nutzen.

Beide gehen von dem durch locale.getpreferredencoding gelieferten Standard-Encoding aus, wenn man nichts anderes angibt.

caiusjuliuscaesar

(Themenstarter)

Anmeldungsdatum:
20. Januar 2009

Beiträge: 307

Zunächst einmal danke.

Jetzt öffne ich, dem Vorschlag folgend, die URL (angeblich gemäß Metadaten in UTF-8 (ohne BOM)), aus der ich lese, mit

1
2
    if 200 == url_requested.code:
        html_content = str(url_requested.read(), encoding='iso8859-15')

Dann kommt folgendes statt "außen" heraus:

1
auÃen

Irgendwie bekommme ich also keinen Grund darein. Quellzeichensatz ist offensichtlich UTF-8 Zielzeichensatz: keine Ahnung. Was benutzt Python in der Konsole?

Gruß und immer wieder danke, CJC

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

Also liest du nicht aus einer HTML-Datei, sondern verarbeitest die Antwort für einen HTTP-Request direkt - was für ein Modul nutzt du für die HTTP-Requests?

Mit requests kannst du das Encoding z.B. übersteuern, falls die Automatik versagt: http://docs.python-requests.org/en/master/user/quickstart/#response-content

caiusjuliuscaesar

(Themenstarter)

Anmeldungsdatum:
20. Januar 2009

Beiträge: 307

seahawk1986 schrieb:

Also liest du nicht aus einer HTML-Datei, sondern verarbeitest die Antwort für einen HTTP-Request direkt - was für ein Modul nutzt du für die HTTP-Requests?

Mit requests kannst du das Encoding z.B. übersteuern, falls die Automatik versagt: http://docs.python-requests.org/en/master/user/quickstart/#response-content

So:

1
from urllib import request

Meintest Du das?

Gruß, CJC

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

Und nutzt du Python2 oder Python3?

Mit Python3 bekommst du den vom Server gesendeten Byte-String zurück (vgl. https://docs.python.org/3/library/urllib.request.html#examples), den du dekodieren musst, um einen (Unicode-)String zu erhalten:

1
2
    if 200 == url_requested.code:
        html_content = url_requested.read().decode('iso8859-15')

urllib ist ziemlich low-Level, d.h. man muss alles selber machen - mit dem requests-Modul (Paket python3-requests) spart man sich da einiges an Arbeit, wenn der Server das Encoding korrekt übermittelt.

caiusjuliuscaesar

(Themenstarter)

Anmeldungsdatum:
20. Januar 2009

Beiträge: 307

Ich benutze Python 3.

Ich habe Deinen Kode statt meines eingefügt, aber keine Änderung im Verhalten:

1
2
3
4
5
    url_requested = request.urlopen('http://des.genealogy.net/search/show/' + str(i))

    if 200 == url_requested.code:
       html_content = url_requested.read().decode('iso8859-15')
       print(html_content)

Also immer noch

1
auÃen

Mein Ziel ist es, au einer html-Seite Tabelleninhalte zwischen den Tags <td> und </td> auszulesen.

Das mit python-requests habe ich nicht verstanden.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

Die Seite sendet UTF-8 enkodiertes HTML, also musst du das so angeben:

1
2
3
4
5
    url_requested = request.urlopen('http://des.genealogy.net/search/show/' + str(i))

    if 200 == url_requested.code:
       html_content = url_requested.read().decode('utf-8')
       print(html_content)

Mit requests könnte das so aussehen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import requests
import sys

# a random i
i = 12345

r = requests.get(f'http://des.genealogy.net/search/show/{i}')
try:
    r.raise_for_status()
except requests.exceptions.HTTPError as error:
    print(error, file=sys.stderr)
else:
    print(r.text)

caiusjuliuscaesar

(Themenstarter)

Anmeldungsdatum:
20. Januar 2009

Beiträge: 307

Danke! Das funktioniert jetzt alles. Gruß, CJC

Antworten |