2017-09-25 51 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

相关问题