【问题标题】:How can I use the python HTMLParser library to extract data from a specific div tag?如何使用 python HTMLParser 库从特定的 div 标签中提取数据?
【发布时间】:2011-03-17 14:30:12
【问题描述】:

我正在尝试使用 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://domain.com/somepage.html")
html = f.read()
p.feed(html)
p.close()

有人能指出我正确的方向吗?我希望类功能获得值 20。

【问题讨论】:

  • 如果你在做大量的 HTML 解析,试试Beautiful Soup
  • 该库是否作为 python 标准库包含在内?我遇到过它,但选择坚持使用 HTMLParser。
  • @zvone 为什么 BeautifulSoup 更适合 html 解析?它仍然是推荐的模块吗?谢谢。
  • @tommy.carstensen BeautifulSoup4 通常被推荐用于网页抓取和解析特定标签的 HTML。它具有定位特定标签的方法,使用 lxml 和 html5lib 库,并为您处理将传入文档转换为 Unicode 并将传出文档转换为 UTF-8。简而言之,它可以在短短几行代码中完成您对丑陋的 HTML 页面所做的一切。查看the bs4 docs! :)
  • @tommy.carstensen 我已经多年没有使用 BeautifulSoup(或解析过的 HTML)了。现在可能有更好的东西。无论如何,它的好处是它在结构糟糕的 HTML 上表现得更好。无效的 HTML 比有效的 HTML 更容易被看到,因此表现良好总是一个加分项。

标签: python html parsing html-parsing


【解决方案1】:

这很好用:

print (soup.find('the tag').text)

【讨论】:

    【解决方案2】:

    你试过BeautifulSoup 吗?

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

    这会在输出时为您提供20

    【讨论】:

      【解决方案3】:

      第 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.someurl.com')
       html = f.read()
       p.feed(html)
       print p.data
       p.close()
      

      `

      【讨论】:

      • 实际上你可以这样做,因为你指定了from HTMLParser import HTMLParser,它允许你直接调用HTMLParser。不幸的是,它们都具有相同的名称,但它们是两个不同的实体。您也可以执行from HTMLParser import HTMLParser as parser 之类的操作,然后使用class MyHTMLParser(parser)
      【解决方案4】:
      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 中(字符串列表,如果没有遇到触发标记,可能为空)。您来自类外部的代码可以在解析结束时直接从实例访问列表,或者您可以为此目的添加适当的访问器方法,具体取决于您的目标。

      通过使用'div''id''remository',实例属性self.tag、@987654330 来代替上面代码中看到的常量文字字符串,可以轻松地使该类更通用@ 和 self.attvalue,由 __init__ 从传递给它的参数中设置——我避免在上面的代码中进行廉价的泛化步骤以避免混淆核心点(跟踪嵌套标签的计数并将数据累积到列表中)录制状态为激活状态)。

      【讨论】:

      • 感谢 Alex,该代码运行良好(除了这一行“if tag == div and self.recording:” - div 应该是一个字符串)。我所说的类返回值的意思实际上正如您所描述的那样,是类中返回所需值的函数。或者我可以轻松访问“数据”变量。我在那里的字典只是我测试可能的解决方案的一些残余:) 感谢您的帮助!
      • +1 表示嵌套 divs 的计数,这对于第一次进行 html 解析的人来说并不那么明显。
      • @Martin,不客气,+1 以发现我的分心——我现在将进行编辑以修复(引用 div 并删除该字典和评论),以便对未来的读者更有用.
      • 如果数据是 unicode 怎么办,例如数据是日文或中文,如何将其附加到 data[] 列表中?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-25
      • 2014-10-16
      • 1970-01-01
      • 2023-03-22
      • 2018-11-10
      • 1970-01-01
      相关资源
      最近更新 更多