2010-07-18 55 views
23

我想從使用python HTMLParser庫的HTML頁面中獲取一個值。我想弄個這個數值就是這個HTML元素中:如何使用python HTMLParser庫從特定的div標籤中提取數據?

... 
<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

+1

如果你做了很多HTML解析,嘗試[美麗的湯(http://www.crummy.com/software/BeautifulSoup/)。 – zvone 2010-07-18 15:58:41

+3

該庫是否包含在python std庫中?我遇到它,但選擇堅持HTMLParser。 – Martin 2010-07-18 16:33:46

+0

@zvone爲什麼BeautifulSoup更適合html解析?它仍然是推薦的模塊?謝謝。 – 2016-03-28 20:11:09

回答

44
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.tagself.attnameself.attvalue,通過__init__從參數設置傳遞給它 - 我避免了上述代碼中的低級泛化步驟,以避免模糊核心點(記錄嵌套標記的計數並在記錄狀態處於活動狀態時將數據累積到列表中)。在3號線

HTMLParser.HTMLParser.__init__(self)

+1

感謝亞歷克斯,該代碼完美工作(除了這條線「如果標記== div和self.recording:」 - div應該是一個字符串)。實際上,正如你所描述的那樣,我所說的返回值的類是類中的一個函數,用於返回所需的值。或者我可以輕鬆訪問'數據'變量。我在那裏的字典只是我的一些殘餘測試可能的解決方案:)謝謝你的幫助! – Martin 2010-07-18 15:38:39

+1

對於嵌套'div'的計數+1,對於第一次使用html解析的人來說並不那麼明顯。 – 2010-07-18 15:49:19

+0

@Martin,不用客氣,+1可以發現我的注意力 - 我現在要編輯修改(引用'div'並刪除該詞典和評論),以便將來讀者更有用。 – 2010-07-18 16:22:11

4

小修正它應該是

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() 

`

+3

實際上你可以這樣做,因爲你指定了'from HTMLParser import HTMLParser',它允許你直接調用HTMLParser。不幸的是,他們都有相同的名字,但他們是兩個不同的實體。你也可以像'從HTMLParser import HTMLParser as parser'那樣做,然後使用'class MyHTMLParser(parser)' – 2011-01-24 23:22:25

22

您試過BeautifulSoup

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

這給你輸出20

0

這完美的作品:

print (soup.find('the tag').text) 
相關問題