Python解析html

來源:互聯網
上載者:User

標籤:

Python 的Beautiful Soup包可以方便的解析html

序言

  之前用python爬取網頁的時候,一直用的是regex或者內建的庫sgmllib裡的SGMLParser。但是遇到複雜一點的情況時,SGMLParser往往就不那麼給力了!(哈,難道說我 too native了?畢竟beautifulSoup是繼承sgmlparser的麼~)所以,我尋尋覓覓尋尋覓覓,發現了BeautifulSoup這麼個玩意。BeautifulSoup提供了很人性化的parser tree,有了它,我們可以簡單的抽取出tagname, attrs, text等等等等...

  install什麼的,看這裡 -> http://www.crummy.com/software/BeautifulSoup/

入門

(ps:其實入門什麼的看官方文檔是最好的了,這裡只是記錄一下簡單的用法。)

(official document : http://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html)

  首先先介紹實際工作中最常用的幾個方法:

  舉例的html代碼(就用官方例子好了):

<html>    <head>        <title>Page title</title>    </head>    <body>        <p id="firstpara" align="center">        This is paragraph<b>one</b>.        </p>        <p id="secondpara" align="blah">        This is paragraph<b>two</b>.        </p>     </body></html>

0、初始化:

soup = BeautifulSoup(html) # html為html原始碼字串,type(html) == str

1、用tag擷取相應代碼塊的剖析樹:

  既然要分析html,首先要找到對我們有用的tag塊,beautiful提供了非常便利的方式。

#當用tag作為搜尋條件時,我們擷取的包含這個tag塊的剖析樹:#<tag><xxx>ooo</xxx></tag>#這裡擷取head這個塊head = soup.find(‘head‘)# or# head = soup.head# or# head = soup.contents[0].contents[0]

    運行後,我們會得到:

<head><title>Page title</title></head>

  這裡我還是推薦使用第二種方法,find方法在當前tag剖析樹(當前這個html代碼塊中)尋找合格子樹並返回。find方法提供多種查詢方式,包括用喜聞樂見的regex哦~之後會詳細介紹。

   contents屬性是一個列表,裡面儲存了該剖析樹的直接兒子。

    如:

html = soup.contents[0] # <html> ... </html>head = html.contents[0] # <head> ... </head>body = html.contents[1] # <body> ... </body>

2、用contents[], parent, nextSibling, previousSibling尋找父子兄弟tag

  為了更加方便靈活的分析html代碼塊,beautifulSoup提供了幾個簡單的方法直接擷取當前tag塊的父子兄弟。

假設我們已經獲得了body這個tag塊,我們想要尋找<html>, <head>, 第一個<p>, 第二個<p>這四個tag塊:

# body = soup.bodyhtml = body.parent # html是body的父親head = body.previousSibling # head和body在同一層,是body的前一個兄弟p1 = body.contents[0] # p1, p2都是body的兒子,我們用contents[0]取得p1p2 = p1.nextSibling # p2與p1在同一層,是p1的後一個兄弟, 當然body.content[1]也可得到print p1.text# u‘This is paragraphone.‘print p2.text# u‘This is paragraphtwo.‘#  注意:1,每個tag的text包括了它以及它子孫的text。2,所有text已經被自動轉#為unicode,如果需要,可以自行轉碼encode(xxx)

  然而,如果我們要尋找祖先或者孫子tag怎麼辦呢?? 用while迴圈嗎? 不, beautifulsoup已經提供了方法。

3、用find, findParent, findNextSibling, findPreviousSibling尋找祖先或者子孫 tag:

  有了上面的基礎,這裡應該很好理解了,例如find方法(我理解和findChild是一樣的),就是以當前節點為起始,遍曆整個子樹,找到後返回。

  而這些方法的複數形式,會找到所有符合要求的tag,以list的方式放回。他們的對應關係是:find->findall, findParent->findParents, findNextSibling->findNextSiblings...

  如:

print soup.findAll(‘p‘)# [<p id="firstpara" align="center">This is paragraph <b>one</b>.</p>, <p id="secondpara" align="blah">This is paragraph <b>two</b>.</p>]

  這裡我們重點講一下find的幾種用法,其他的類比:

  find(name=None, attrs={}, recursive=True, text=None, **kwargs)

(ps:只講幾種用法,完整請看官方link :http://www.crummy.com/software/BeautifulSoup/bs3/documentation.zh.html#The%20basic%20find%20method:%20findAll%28name,%20attrs,%20recursive,%20text,%20limit,%20**kwargs%29)

  1) 搜尋tag:

find(tagname)        # 直接搜尋名為tagname的tag 如:find(‘head‘)find(list)           # 搜尋在list中的tag,如: find([‘head‘, ‘body‘])find(dict)           # 搜尋在dict中的tag,如:find({‘head‘:True, ‘body‘:True})find(re.compile(‘‘)) # 搜尋符合正則的tag, 如:find(re.compile(‘^p‘)) 搜尋以p開頭的tagfind(lambda)         # 搜尋函數返回結果為true的tag, 如:find(lambda name: if len(name) == 1) 搜尋長度為1的tagfind(True)           # 搜尋所有tag

  2) 搜尋屬性(attrs):

find(id=‘xxx‘)                                  # 尋找id屬性為xxx的find(attrs={id=re.compile(‘xxx‘), algin=‘xxx‘}) # 尋找id屬性符合正則且algin屬性為xxx的find(attrs={id=True, algin=None})               # 尋找有id屬性但是沒有algin屬性的

  3) 搜尋文字(text):

       注意,文字的搜尋會導致其他搜尋給的值如:tag, attrs都失效。方法與搜尋tag一致

  4) recursive, limit:

  recursive=False表示只搜尋直接兒子,否則搜尋整個子樹,預設為True。

  當使用findAll或者類似返回list的方法時,limit屬性用於限制返回的數量,如findAll(‘p‘, limit=2): 返回首先找到的兩個tag

4、用next,previous尋找上下文tag(少用)

  這裡我們主要看看next, next是取得當前的tag的下一個(按代碼從上到下的順序)tag塊。這與contents是不一樣的,千萬別混淆了哦^ ^

  我們舉個栗子來看看

<a>    a    <b>b</b>    <c>c</c> </a>

    我們看看next的實際效果:

a = soup.ab = soup.bn1 = b.nextn2 = n1.next

   輸出一下:

print a.next# u‘a‘print n1# u‘b‘print n2# <c>c</c>

    所以,next僅僅是擷取文檔上的“下一個”的tag,和剖析樹中的位置無關。

    當然也有findNext和findAllNext方法。

   至於previous, 表示上一個tag塊,就類比一下吧~^ ^

   原博:http://www.cnblogs.com/twinsclover/archive/2012/04/26/2471704.html

更多

    Soupy也可以方便的解析html文檔,它是基於Beautiful Soup的python庫,與其相比,能夠更快捷的寫出複雜的html查詢,

    github:

https://github.com/ChrisBeaumont/soupy?utm_content=buffer6e5b7&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer

    api:

http://soupy.readthedocs.org/en/stable/getting_started.html


    熟悉jquery也可用pyquery對html文檔進行解析。


Python解析html

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.