it-swarm.com.ru

Как я могу использовать библиотеку Python HTMLParser для извлечения данных из определенного тега div?

Я пытаюсь получить значение из HTML-страницы, используя библиотеку Python HTMLParser. Значение, которое я хочу получить, находится внутри этого 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.

30
Martin
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, self.attname и self.attvalue, установленные __init__ из передаваемых ему аргументов - - Я избегал этого дешевого шага обобщения в приведенном выше коде, чтобы не затенять основные точки (отслеживать количество вложенных тегов и накапливать данные в списке, когда состояние записи активно).

49
Alex Martelli

Вы пробовали BeautifulSoup

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

Это дает вам 20 на выходе.

23
modzello86

Небольшая коррекция на линии 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()

`

5
pshirishreddy

Это прекрасно работает:

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