2017-09-25 60 views
0

我正在使用html.parser和urllib.request。我不打算使用任何非本地模塊,但如果有必要,我願意使用其他本地模塊。 目前(的一部分),我的代碼如下所示:我想檢索特定行上的html標記內的文本

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

我遇到的問題是,HTMLParser.getpos總是返回的元組(1,x),其中x是一個數字,每次增加但看似隨機),像這樣:

 
(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) 

我覺得整個html.parser模塊是寫在一個非常愚蠢的辦法,可能已經想到了要好得多。顯然它很有效,但它是違反直覺的。
全碼:

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

你想要你的代碼做什麼,它不正確?你想要打印第167行的HTML嗎?你能告訴我們你正在解析的HTML是什麼樣的嗎? (如果它說它只在第一行,我猜這是一個單行文件)。另外我真的不知道是什麼調用一個Python庫,你堅持用這個愚蠢的增加來解決這個問題。 –

+0

HTML是像[this]這樣的頁面(https://www.azlyrics.com/lyrics/aha/takeonme.html)。我試圖從始終在第167行的div標籤中取出歌詞(字符串)數據,並將其分配給字符串變量。我說這是愚蠢的,因爲它是 - 它增加了這個問題,因爲這是對其他人可能使用更直觀的模塊的警告。我不會使用它,我必須使用它,因爲我的學校電腦只有本地模塊,所以我確保我沒有5個人告訴我使用BeautifulSoup。 – Feesih0ps

+0

您可以發佈產生該輸出的完整代碼示例嗎?它似乎對我來說工作得很好。 –

回答

0

關於如何從一個div解析數據 - 當你在這些點之間進入div和退出DIV,積累數據,你應該跟蹤。這對圖書館來說很容易做到,而且與實際的解析有很大的距離,儘管我不打算討論什麼是愚蠢的,什麼不是。

您的行號問題是因爲您正在使用str來讀取bytes對象。在翻譯中,你可以看到爲什麼這是一個問題:

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

實際上它並不將其轉換爲一種等價的字符串,而是一個字符串表示。這意味着字節對象中的換行符被字面表示爲\n,所以你沒有得到任何行號。要解碼一個字節對象,你應該使用.decode。下面的代碼應該工作:

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) 

對於我這個正確的輸出是這樣的:

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

說完看着網頁,我必須得出結論:你是對的 - 它bizzarely結構化的,只有這樣,才能通過行號來標識歌詞div,或者可能是以前div的數量 - 如果行號失敗,則可以嘗試在handle_starttag之前保持div的計數。

+0

謝謝!很好地解釋和改進了我的代碼! – Feesih0ps

相關問題