CSS 選擇器BeautifulSoup4解析器

      網友投稿 1136 2025-03-31

      和 lxml 一樣,Beautiful Soup 也是一個HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 數據。


      lxml 只會局部遍歷,而Beautiful Soup 是基于HTML DOM的,會載入整個文檔,解析整個DOM樹,因此時間和內存開銷都會大很多,所以性能要低于lxml。

      BeautifulSoup 用來解析 HTML 比較簡單,API非常人性化,支持CSS選擇器、Python標準庫中的HTML解析器,也支持 lxml 的 XML解析器。

      Beautiful Soup 3 目前已經停止開發,推薦現在的項目使用Beautiful Soup 4。使用 pip 安裝即可:pip install beautifulsoup4

      官方文檔:http://beautifulsoup.readthedocs.io/zh_CN/v4.4.0

      示例:

      首先必須要導入 bs4 庫

      # beautifulsoup4_test.py

      from bs4 import BeautifulSoup

      html = """

      The Dormouse's story

      The Dormouse's story

      Once upon a time there were three little sisters; and their names were

      ,

      Lacie and

      Tillie;

      and they lived at the bottom of a well.

      ...

      """

      #創建 Beautiful Soup 對象

      soup = BeautifulSoup(html)

      #打開本地 HTML 文件的方式來創建對象

      #soup = BeautifulSoup(open('index.html'))

      #格式化輸出 soup 對象的內容

      print soup.prettify()

      運行結果:

      </p><p>The Dormouse's story</p><p>

      The Dormouse's story

      Once upon a time there were three little sisters; and their names were

      ,

      Lacie

      and

      Tillie

      ;

      and they lived at the bottom of a well.

      ...

      如果我們在 IPython2 下執行,會看到這樣一段警告:

      意思是,如果我們沒有顯式地指定解析器,所以默認使用這個系統的最佳可用HTML解析器(“lxml”)。如果你在另一個系統中運行這段代碼,或者在不同的虛擬環境中,使用不同的解析器造成行為不同。

      但是我們可以通過soup = BeautifulSoup(html,“lxml”)方式指定lxml解析器。

      四大對象種類

      Beautiful Soup將復雜HTML文檔轉換成一個復雜的樹形結構,每個節點都是Python對象,所有對象可以歸納為4種:

      Tag

      NavigableString

      BeautifulSoup

      Comment

      1. Tag

      Tag 通俗點講就是 HTML 中的一個個標簽,例如:

      The Dormouse's story

      The Dormouse's story

      上面的?title?head?a?p等等 HTML 標簽加上里面包括的內容就是 Tag,那么試著使用 Beautiful Soup 來獲取 Tags:

      from bs4 import BeautifulSoup

      html = """

      The Dormouse's story

      The Dormouse's story

      Once upon a time there were three little sisters; and their names were

      ,

      Lacie and

      Tillie;

      and they lived at the bottom of a well.

      ...

      """

      #創建 Beautiful Soup 對象

      soup = BeautifulSoup(html)

      print soup.title

      # The Dormouse's story

      print soup.head

      # The Dormouse's story

      print soup.a

      #

      print soup.p

      #

      The Dormouse's story

      print type(soup.p)

      #

      我們可以利用 soup 加標簽名輕松地獲取這些標簽的內容,這些對象的類型是bs4.element.Tag。但是注意,它查找的是在所有內容中的第一個符合要求的標簽。如果要查詢所有的標簽,后面會進行介紹。

      對于 Tag,它有兩個重要的屬性,是 name 和 attrs

      print soup.name

      # [document] #soup 對象本身比較特殊,它的 name 即為 [document]

      print soup.head.name

      # head #對于其他內部標簽,輸出的值便為標簽本身的名稱

      print soup.p.attrs

      # {'class': ['title'], 'name': 'dromouse'}

      # 在這里,我們把 p 標簽的所有屬性打印輸出了出來,得到的類型是一個字典。

      print soup.p['class'] # soup.p.get('class')

      # ['title'] #還可以利用get方法,傳入屬性的名稱,二者是等價的

      soup.p['class'] = "newClass"

      print soup.p # 可以對這些屬性和內容等等進行修改

      #

      The Dormouse's story

      del soup.p['class'] # 還可以對這個屬性進行刪除

      print soup.p

      #

      The Dormouse's story

      2. NavigableString

      既然我們已經得到了標簽的內容,那么問題來了,我們要想獲取標簽內部的文字怎么辦呢?很簡單,用 .string 即可,例如

      print soup.p.string

      # The Dormouse's story

      print type(soup.p.string)

      # In [13]:

      3. BeautifulSoup

      BeautifulSoup 對象表示的是一個文檔的內容。大部分時候,可以把它當作 Tag 對象,是一個特殊的 Tag,我們可以分別獲取它的類型,名稱,以及屬性來感受一下

      print type(soup.name)

      #

      print soup.name

      # [document]

      print soup.attrs # 文檔本身的屬性為空

      # {}

      4. Comment

      Comment 對象是一個特殊類型的 NavigableString 對象,其輸出的內容不包括注釋符號。

      print soup.a

      #

      print soup.a.string

      # Elsie

      print type(soup.a.string)

      #

      a 標簽里的內容實際上是注釋,但是如果我們利用 .string 來輸出它的內容時,注釋符號已經去掉了。

      遍歷文檔樹

      1. 直接子節點 :.contents?.children?屬性

      .content

      tag 的 .content 屬性可以將tag的子節點以列表的方式輸出

      print soup.head.contents

      #[The Dormouse's story]

      輸出方式為列表,我們可以用列表索引來獲取它的某一個元素

      print soup.head.contents[0]

      #The Dormouse's story

      .children

      它返回的不是一個 list,不過我們可以通過遍歷獲取所有子節點。

      我們打印輸出 .children 看一下,可以發現它是一個 list 生成器對象

      print soup.head.children

      #

      for child in soup.body.children:

      print child

      結果:

      The Dormouse's story

      Once upon a time there were three little sisters; and their names were

      ,

      Lacie and

      Tillie;

      and they lived at the bottom of a well.

      ...

      2. 所有子孫節點:?.descendants?屬性

      .contents 和 .children 屬性僅包含tag的直接子節點,.descendants 屬性可以對所有tag的子孫節點進行遞歸循環,和 children類似,我們也需要遍歷獲取其中的內容。

      for child in soup.descendants:

      print child

      運行結果:

      The Dormouse's story

      The Dormouse's story

      Once upon a time there were three little sisters; and their names were

      ,

      Lacie and

      Tillie;

      and they lived at the bottom of a well.

      ...

      The Dormouse's story

      The Dormouse's story

      The Dormouse's story

      The Dormouse's story

      Once upon a time there were three little sisters; and their names were

      ,

      Lacie and

      Tillie;

      and they lived at the bottom of a well.

      ...

      The Dormouse's story

      The Dormouse's story

      The Dormouse's story

      Once upon a time there were three little sisters; and their names were

      ,

      Lacie and

      Tillie;

      and they lived at the bottom of a well.

      Once upon a time there were three little sisters; and their names were

      Elsie

      ,

      Lacie

      Lacie

      and

      Tillie

      Tillie

      ;

      and they lived at the bottom of a well.

      ...

      ...

      3. 節點內容:?.string?屬性

      如果tag只有一個 NavigableString 類型子節點,那么這個tag可以使用 .string 得到子節點。如果一個tag僅有一個子節點,那么這個tag也可以使用 .string 方法,輸出結果與當前唯一子節點的 .string 結果相同。

      通俗點說就是:如果一個標簽里面沒有標簽了,那么 .string 就會返回標簽里面的內容。如果標簽里面只有唯一的一個標簽了,那么 .string 也會返回最里面的內容。例如:

      print soup.head.string

      #The Dormouse's story

      print soup.title.string

      #The Dormouse's story

      搜索文檔樹

      1.find_all(name, attrs, recursive, text, **kwargs)

      1)name 參數

      name 參數可以查找所有名字為 name 的tag,字符串對象會被自動忽略掉

      A.傳字符串

      最簡單的過濾器是字符串.在搜索方法中傳入一個字符串參數,Beautiful Soup會查找與字符串完整匹配的內容,下面的例子用于查找文檔中所有的標簽:

      soup.find_all('b')

      # [The Dormouse's story]

      print soup.find_all('a')

      #[, Lacie, Tillie]

      B.傳正則表達式

      如果傳入正則表達式作為參數,Beautiful Soup會通過正則表達式的 match() 來匹配內容.下面例子中找出所有以b開頭的標簽,這表示和標簽都應該被找到

      import re

      CSS 選擇器:BeautifulSoup4解析器

      for tag in soup.find_all(re.compile("^b")):

      print(tag.name)

      # body

      # b

      C.傳列表

      如果傳入列表參數,Beautiful Soup會將與列表中任一元素匹配的內容返回.下面代碼找到文檔中所有標簽和標簽:

      soup.find_all(["a", "b"])

      # [The Dormouse's story,

      # Elsie,

      # Lacie,

      # Tillie]

      2)keyword 參數

      soup.find_all(id='link2')

      # [Lacie]

      3)text 參數

      通過 text 參數可以搜搜文檔中的字符串內容,與 name 參數的可選值一樣, text 參數接受 字符串 , 正則表達式 , 列表

      soup.find_all(text="Elsie")

      # [u'Elsie']

      soup.find_all(text=["Tillie", "Elsie", "Lacie"])

      # [u'Elsie', u'Lacie', u'Tillie']

      soup.find_all(text=re.compile("Dormouse"))

      [u"The Dormouse's story", u"The Dormouse's story"]

      CSS選擇器

      這就是另一種與 find_all 方法有異曲同工之妙的查找方法.

      寫 CSS 時,標簽名不加任何修飾,類名前加.,id名前加#

      在這里我們也可以利用類似的方法來篩選元素,用到的方法是?soup.select(),返回類型是?list

      (1)通過標簽名查找

      print soup.select('title')

      #[The Dormouse's story]

      print soup.select('a')

      #[, Lacie, Tillie]

      print soup.select('b')

      #[The Dormouse's story]

      (2)通過類名查找

      print soup.select('.sister')

      #[, Lacie, Tillie]

      (3)通過 id 名查找

      print soup.select('#link1')

      #[]

      (4)組合查找

      組合查找即和寫 class 文件時,標簽名與類名、id名進行的組合原理是一樣的,例如查找 p 標簽中,id 等于 link1的內容,二者需要用空格分開

      print soup.select('p #link1')

      #[]

      直接子標簽查找,則使用?>?分隔

      print soup.select("head > title")

      #[The Dormouse's story]

      (5)屬性查找

      查找時還可以加入屬性元素,屬性需要用中括號括起來,注意屬性和標簽屬于同一節點,所以中間不能加空格,否則會無法匹配到。

      print soup.select('a[class="sister"]')

      #[, Lacie, Tillie]

      print soup.select('a[)

      #[]

      同樣,屬性仍然可以與上述查找方式組合,不在同一節點的空格隔開,同一節點的不加空格

      print soup.select('p a[)

      #[]

      (6) 獲取內容

      以上的 select 方法返回的結果都是列表形式,可以遍歷形式輸出,然后用 get_text() 方法來獲取它的內容。

      soup = BeautifulSoup(html, 'lxml')

      print type(soup.select('title'))

      print soup.select('title')[0].get_text()

      for title in soup.select('title'):

      print title.get_text()

      CSS HTML

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:怎么能加不同的頁眉(如何加不同的頁眉)
      下一篇:G Suit 介紹
      相關文章
      久久精品国产亚洲av四虎| 亚洲色无码专区在线观看| 亚洲精品狼友在线播放| 亚洲Av无码国产情品久久 | 亚洲精品成a人在线观看☆| 亚洲图片中文字幕| 亚洲国产成人精品无码一区二区 | 中文字幕亚洲专区| 亚洲日韩国产成网在线观看| 亚洲国产精品激情在线观看| 成人亚洲综合天堂| 亚洲国产成人a精品不卡在线| 亚洲国产成人久久笫一页| 狠狠色婷婷狠狠狠亚洲综合 | 亚洲国产精品成人综合色在线婷婷 | 国产成人va亚洲电影| 亚洲av中文无码| 国产日产亚洲系列最新| 亚洲人成网7777777国产| 亚洲国产精品无码久久久不卡| 亚洲va久久久噜噜噜久久狠狠 | 无码欧精品亚洲日韩一区| 亚洲国产一区在线| 亚洲男人天堂影院| 亚洲免费福利视频| 亚洲中文字幕久久精品无码A| 亚洲日韩精品无码专区加勒比☆ | 亚洲日产乱码一二三区别| 国产精品亚洲专区无码牛牛 | 亚洲国产高清视频在线观看| 456亚洲人成影院在线观| 亚洲熟妇少妇任你躁在线观看| 亚洲日本中文字幕天天更新| 亚洲成a人无码av波多野按摩 | 亚洲偷自精品三十六区| 亚洲老熟女五十路老熟女bbw | 久久久久国产亚洲AV麻豆| 亚洲AV无码国产精品色午友在线| 日本久久久久亚洲中字幕| 国产精品高清视亚洲精品| 亚洲人成电影网站色|