1. 程式人生 > >BeautifulSoup中select的使用方法

BeautifulSoup中select的使用方法

html = """
  <html><head><title>The Dormouse's story</title></head>
  <body>
  <p class="title" name="dromouse"><b>The Dormouse's story</b></p>
  <p class="story">Once upon a time there were three little sisters; and their names were
  <a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
  <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
  <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
  and they lived at the bottom of a well.</p>
 <p class="story">...</p>
 """

我們在寫 CSS 時,標籤名不加任何修飾,類名(class="className"引號內即為類名)前加點,id名(id="idName"引號前即為id名)前加 #,在這裡我們也可以利用類似的方法來篩選元素,用到的方法是 soup.select(),返回型別是 list
(1)通過標籤名查詢
 

print soup.select('title') 
#[<title>The Dormouse's story</title>]

print soup.select(‘a’)
#[<a class=“sister” href=“http://example.com/elsie

” id=“link1”><!-- Elsie --></a>, <a class=“sister” href=“http://example.com/lacie” id=“link2”>Lacie</a>, <a class=“sister” href=“http://example.com/tillie” id=“link3”>Tillie</a>]

print soup.select(‘b’)
#[<b>The Dormouse’s story</b>]

(2)通過類名查詢
 

print soup.select('.sister')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]

(3)通過 id 名查詢
 

print soup.select('#link1')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]

(4)組合查詢

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

print soup.select('p #link1')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]

直接子標籤查詢
 

print soup.select("head > title")
#[<title>The Dormouse's story</title>]

(5)屬性查詢

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

print soup.select("head > title")
#[<title>The Dormouse's story</title>]

print soup.select(‘a[href=“http://example.com/elsie”]’)
#[<a class=“sister” href=“http://example.com/elsie” id=“link1”><!-- Elsie --></a>]

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

print soup.select('p a[href="http://example.com/elsie"]')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]

 

 

BeautifulSoup支援CSS選擇器是令人驚喜的,這大大方便了我們對特定標籤的選取。那麼接下來就來試驗一下。 
比如現在我們需要選取搜狗主頁中導航欄中導向“知乎”的連結。 
分析文件結構大概有這幾個比較容易區分的層級特點:


  
  1. <div class="top-nav">
  2. <ul>
  3. ...
  4. <li class="cur"> <span>網頁 </span> </li>
  5. href="http://zhihu.sogou.com/" uigs-id="nav_zhihu" id="zhihu">知乎 </a> </li>
  6. <li> <a onclick="st(this,'40030500','pic')" href="http://pic.sogou.com" uigs-id="nav_pic" id="pic">圖片 </a> </li>
  7. ...
  8. </ul>
  9. </div>

      鑑於如此的結構,我們可以使用類選擇器選擇“.top-nav”然後使用後代選擇其選擇“ul”標籤和“li”標籤,於是整個選擇器可以寫為“.top-nav ul li”,在程式碼中實現如下:

      
        
      1. li = bs.select( '.top-nav ul li')
      2. print( "result len is", len(li))
      3. for tag in li:
      4. print(tag)

          得到如下輸出:

          
            
          1. result len is 10
          2. <li> <a href="http://news.sogou.com" id="news" onclick="st(this,'40030300','news')" uigs-id="nav_news">新聞 </a> </li>
          3. <li class="cur"> <span>網頁 </span> </li>
          4. <li> <a href="http://weixin.sogou.com/" id="weixinch" onclick="st(this,'73141200','weixin')" uigs-id="nav_weixin">微信 </a> </li>
          5. <li> <a href="http://zhihu.sogou.com/" id="zhihu" onclick="st(this,'40051200','zhihu')" uigs-id="nav_zhihu">知乎 </a> </li>
          6. <li> <a href="http://pic.sogou.com" id="pic" onclick="st(this,'40030500','pic')" uigs-id="nav_pic">圖片 </a> </li>
          7. ...

              但裡面出現了“網頁”這個沒有連結到其他地址的項,要如何將之過濾掉呢。可以結合filter函式進行處理,如下:

              
                
              1. def hasHttpLink(tag):
              2. """此時的tag為<li>標籤,需要取得其中的<a>再來進行判斷"""
              3. return tag.a is not None and tag.a.get( 'href').startswith( "http")
              4. for tag in filter(hasHttpLink, li):
              5. print(tag)

                  結果中已經過濾掉“網頁”這項了:

                  
                    
                  1. <li> <a href="http://news.sogou.com" id="news" onclick="st(this,'40030300','news')" uigs-id="nav_news">新聞 </a> </li>
                  2. <li> <a href="http://weixin.sogou.com/" id="weixinch" onclick="st(this,'73141200','weixin')" uigs-id="nav_weixin">微信 </a> </li>
                  3. <li> <a href="http://zhihu.sogou.com/" id="zhihu" onclick="st(this,'40051200','zhihu')" uigs-id="nav_zhihu">知乎 </a> </li>
                  4. <li> <a href="http://pic.sogou.com" id="pic" onclick="st(this,'40030500','pic')" uigs-id="nav_pic">圖片 </a> </li>
                  5. ...

                      其中filter高階函式進行過濾時還可以使用正則來進行匹配篩選。 
                      不過一般情況下僅僅使用selector就能比較精確的獲取結果集了,因此filter也不用寫得很複雜。