我想检索特定行上 html 标记内的文本

I want to retrieve the text inside a html tag on a specific line

我正在使用 html.parser 和 urllib.request。我不会使用任何非本地模块,但如果有必要,我愿意使用其他本地模块。 目前(部分)我的代码如下所示:

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

我遇到的问题是 HTMLParser.getpos 总是 returns (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))

关于如何从 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
...

看过页面后我必须得出结论你是对的 - 它的结构很奇怪,识别歌词的唯一方法 div 是通过行号,或者可能是之前的行号 div s - 如果行号失败,你可以尝试保持在 handle_starttag.

中遇到的 divs 的计数