如何使用Python的HTMLParser库从特定的div标签中提取数据?

46 投票
4 回答
139004 浏览
提问于 2025-04-16 01:28

我正在尝试使用Python的HTMLParser库从一个HTML页面中提取一个值。我想要获取的值在这个HTML元素里:

...
<div id="remository">20</div>
...

这是我目前写的HTMLParser类:

class LinksParser(HTMLParser.HTMLParser):
  def __init__(self):
    HTMLParser.HTMLParser.__init__(self)
    self.seen = {}

  def handle_starttag(self, tag, attributes):
    if tag != 'div': return
    for name, value in attributes:
    if name == 'id' and value == 'remository':
      #print value
      return

  def handle_data(self, data):
    print data

p = LinksParser()
f = urllib.urlopen("http://example.com/somepage.html")
html = f.read()
p.feed(html)
p.close()

我希望这个类能够提取出值20。

4 个回答

6

第3行有个小错误

HTMLParser.HTMLParser.__init__(self)

应该改成

HTMLParser.__init__(self)

不过下面这个对我来说是有效的

import urllib2

from HTMLParser import HTMLParser

class MyHTMLParser(HTMLParser):

  def __init__(self):
    HTMLParser.__init__(self)
    self.recording = 0
    self.data = []
  def handle_starttag(self, tag, attrs):
    if tag == 'required_tag':
      for name, value in attrs:
        if name == 'somename' and value == 'somevale':
          print name, value
          print "Encountered the beginning of a %s tag" % tag
          self.recording = 1

  def handle_endtag(self, tag):
    if tag == 'required_tag':
      self.recording -=1
      print "Encountered the end of a %s tag" % tag

  def handle_data(self, data):
    if self.recording:
      self.data.append(data)

 p = MyHTMLParser()
 f = urllib2.urlopen('http://www.example.com')
 html = f.read()
 p.feed(html)
 print(p.data)
 p.close()
31

你试过 BeautifulSoup 吗?

from bs4 import BeautifulSoup
soup = BeautifulSoup('<div id="remository">20</div>')
tag=soup.div
print(tag.string)

这样做会输出 20

69
class LinksParser(HTMLParser.HTMLParser):
  def __init__(self):
    HTMLParser.HTMLParser.__init__(self)
    self.recording = 0
    self.data = []

  def handle_starttag(self, tag, attributes):
    if tag != 'div':
      return
    if self.recording:
      self.recording += 1
      return
    for name, value in attributes:
      if name == 'id' and value == 'remository':
        break
    else:
      return
    self.recording = 1

  def handle_endtag(self, tag):
    if tag == 'div' and self.recording:
      self.recording -= 1

  def handle_data(self, data):
    if self.recording:
      self.data.append(data)

self.recording 用来计算从一个“触发”标签开始的嵌套 div 标签的数量。当我们在一个以触发标签为根的子树中时,我们会把数据累积到 self.data 里。

解析结束时的数据会留在 self.data 中(这是一个字符串列表,如果没有遇到触发标签,可能是空的)。你可以在解析结束后直接从实例中访问这个列表,或者根据你的具体需求添加合适的方法来获取这些数据。

这个类可以通过使用实例属性 self.tagself.attnameself.attvalue 来变得更通用,而不是在上面的代码中使用固定的字符串 'div''id''remository'。这些属性可以通过 __init__ 方法从传入的参数中设置。我在上面的代码中避免了这种简单的通用化,以免掩盖核心要点(跟踪嵌套标签的数量,并在录制状态激活时将数据累积到列表中)。

撰写回答