2017-09-25 1 views
0

Ich verwende html.parser und urllib.request. Ich werde keine nicht-nativen Module verwenden, aber ich bin offen dafür, andere native zu verwenden, wenn sie notwendig sind. Zeit (ein Teil von) mein Code sieht wie folgt aus:Ich möchte den Text innerhalb eines HTML-Tags in einer bestimmten Zeile abrufen

class MyHTMLParser(HTMLParser): 
    def handle_data(self, data): 
     if self.getpos()[0] == 167: 
      print(self.data) 

Das Problem, das ich habe ist, dass HTMLParser.getpos gibt immer ein Tupel von (1, x), wobei x eine Zahl, die jedes Mal erhöht , aber scheinbar zufällig), wie folgt aus:

 
(1, 21) 
(1, 41) 
(1, 51) 
(1, 77) 
(1, 134) 
(1, 206) 
(1, 406) 
(1, 509) 
(1, 553) 
(1, 627) 
(1, 680) 
(1, 784) 
(1, 1143) 
(1, 1368) 

ich fühle mich wie der ganze html.parser Modul in einer sehr dummen Art geschrieben und viel besser durchdacht worden sein könnte. Offensichtlich funktioniert es, aber es ist kontraintuitiv.
Voll Code:

from urllib.request import * 
from html.parser import HTMLParser 
class MyHTMLParser(HTMLParser): 
    def handle_data(self, data): 
     print(self.getpos()) 
     if self.getpos()[0] == 167: 
     print(data) 
parser = MyHTMLParser() 
html = urlopen("https://www.azlyrics.com/lyrics/aha/takeonme.html").read() 
parser.feed(str(html)) 
+0

Was ist es, was Sie wollen, dass Ihr Code es nicht richtig macht? Versuchen Sie, die 167. HTML-Zeile zu drucken? Können Sie uns sagen, wie der zu analysierende HTML-Code aussieht? (wenn es sagt, dass es nur in Zeile 1 ist, würde ich denken, es ist eine einzeilige Datei). Ich sehe auch nicht wirklich, was eine Python-Bibliothek aufruft, auf der du stehst, wenn du dumm bist, fügt die Frage hinzu. –

+0

Die HTML ist eine Seite wie [diese] (https://www.azlyrics.com/lyrics/aha/takeonme.html). Ich versuche, die Text- (String-) Daten aus einem div-Tag zu entnehmen, das sich immer in Zeile 167 befindet, und es einer String-Variablen zuzuordnen. Ich sage, dass es dumm ist, weil es - es fügt der Frage hinzu, weil es eine Warnung für andere Leute ist, vielleicht ein intuitiveres Modul zu verwenden. Ich benutze es nicht, ich muss es verwenden, weil meine Schulcomputer nur native Module haben, also sorge ich dafür, dass ich nicht 5 Leute bekomme, die mir sagen, dass ich BeautifulSoup benutzen soll. – Feesih0ps

+0

Konnten Sie das vollständige Codebeispiel, das diese Ausgabe produziert, veröffentlichen? Es scheint für mich gut zu funktionieren. –

Antwort

0

In Bezug auf, wie Daten von einem div analysieren - sollten Sie verfolgen, wenn Sie die div und beenden Sie die div eingeben, und sammeln sie Daten zwischen diesen Punkten. Das ist leicht mit der Bibliothek zu tun und liegt viel näher beim eigentlichen Parsing, obwohl ich nicht in eine Debatte darüber gehen werde, was dumm ist und was nicht.

Ihr Problem mit Zeilennummern liegt darin, dass Sie str verwenden, um ein bytes Objekt zu lesen. Im Interpreter können Sie sehen, warum dies ein Problem ist:

>>> str(b"ab\nc") 
"b'ab\\nc'" 

Es tatsächlich zu einer Art von gleichwertiger Zeichenfolge nicht konvertieren, sondern auf eine String-Darstellung. Das bedeutet, dass Zeilenumbrüche im Byte-Objekt wörtlich als \n dargestellt werden, sodass Sie keine Zeilennummern erhalten. Um ein Byte-Objekt zu dekodieren, sollten Sie .decode verwenden. Der folgende Code sollte funktionieren:

import sys 

from html.parser import HTMLParser 
from urllib.request import urlopen 

class LyricParser(HTMLParser): 
    def get_lyrics(self, html): 
     self.read_lyrics = False 
     self.lyrics = [] 
     self.feed(html) 
     return "".join(self.lyrics) 

    def handle_starttag(self, tag, attrs): 
     if tag == "div" and self.getpos()[0] == 167: 
      self.read_lyrics = True 

    def handle_data(self, data): 
     if self.read_lyrics: 
      self.lyrics.append(data) 

    def handle_endtag(self, tag): 
     if tag == "div": 
      self.read_lyrics = False 

parser = LyricParser() 
page = urlopen("https://www.azlyrics.com/lyrics/aha/takeonme.html") 
lyrics = parser.get_lyrics(page.read().decode('utf-8')) 
print(lyrics) 

Für mich gibt richtig so etwas wie:

Talking away 
I don't know what I'm to say 
I'll say it anyway 
Today's another day to find you 
... 

auf der Seite sah Nachdem ich schließen müssen Sie haben Recht - es ist bizzarely strukturiert, und die einzige Möglichkeit, Identifizieren des Liedtextes div ist nach Zeilennummer oder vielleicht Anzahl der vorherigen divs - wenn die Zeilennummer jemals fehlschlägt, könntest du versuchen, die Anzahl der divs in handle_starttag zu halten.

+0

Danke! Gut erklärt und verbessert meinen Code sehr! – Feesih0ps

Verwandte Themen