Python BeautifulSoup4 select方法執行css選擇器
阿新 • • 發佈:2018-12-26
初識爬蟲,使用urllib結合強大的BeautifulSoup簡單寫了下程式碼。看參考書上主要講解了find方法的使用,但發現其是還支援css選擇器語法選擇,於是試驗了一下。
環境為:ubuntu12.04 + pycharm2017.1.3 + python3.6 + urllib + beautifulsoup4
構造BeautifulSoup物件
首先,我是以爬取搜狗搜尋的主頁來試驗的。其結構大概如此
編寫爬蟲程式碼如下
from urllib import request
from bs4 import BeautifulSoup
html = request.urlopen("https://www.sogou.com/" ) #執行請求
bs = BeautifulSoup(html) #將請求結果傳遞給bs構造物件
print(bs.getText) #輸出整個bs的內容
程式碼很簡單清晰,只是將bs物件構造處理直接輸出其內容。當然這體現不出BeautifulSoup的強大,因為這直接通過html物件也能得到。但不要心急,接下來讓我們繼續試驗BeautifulSoup的CSS選擇器功能。
使用BeautifulSoup select方法提取內容
BeautifulSoup支援CSS選擇器是令人驚喜的,這大大方便了我們對特定標籤的選取。那麼接下來就來試驗一下。
比如現在我們需要選取搜狗主頁中導航欄中導向“知乎”的連結。
分析文件結構大概有這幾個比較容易區分的層級特點:
<div class="top-nav">
<ul>
...
<li class="cur"><span>網頁</span></li>
href="http://zhihu.sogou.com/" uigs-id="nav_zhihu" id="zhihu">知乎</a></li>
<li><a onclick="st(this,'40030500','pic')" href="http://pic.sogou.com" uigs-id ="nav_pic" id="pic">圖片</a></li>
...
</ul>
</div>
鑑於如此的結構,我們可以使用類選擇器選擇“.top-nav”然後使用後代選擇其選擇“ul”標籤和“li”標籤,於是整個選擇器可以寫為“.top-nav ul li”,在程式碼中實現如下:
li = bs.select('.top-nav ul li')
print("result len is", len(li))
for tag in li:
print(tag)
得到如下輸出:
result len is 10
<li><a href="http://news.sogou.com" id="news" onclick="st(this,'40030300','news')" uigs-id="nav_news">新聞</a></li>
<li class="cur"><span>網頁</span></li>
<li><a href="http://weixin.sogou.com/" id="weixinch" onclick="st(this,'73141200','weixin')" uigs-id="nav_weixin">微信</a></li>
<li><a href="http://zhihu.sogou.com/" id="zhihu" onclick="st(this,'40051200','zhihu')" uigs-id="nav_zhihu">知乎</a></li>
<li><a href="http://pic.sogou.com" id="pic" onclick="st(this,'40030500','pic')" uigs-id="nav_pic">圖片</a></li>
...
但裡面出現了“網頁”這個沒有連結到其他地址的項,要如何將之過濾掉呢。可以結合filter函式進行處理,如下:
def hasHttpLink(tag):
"""此時的tag為<li>標籤,需要取得其中的<a>再來進行判斷"""
return tag.a is not None and tag.a.get('href').startswith("http")
for tag in filter(hasHttpLink, li):
print(tag)
結果中已經過濾掉“網頁”這項了:
<li><a href="http://news.sogou.com" id="news" onclick="st(this,'40030300','news')" uigs-id="nav_news">新聞</a></li>
<li><a href="http://weixin.sogou.com/" id="weixinch" onclick="st(this,'73141200','weixin')" uigs-id="nav_weixin">微信</a></li>
<li><a href="http://zhihu.sogou.com/" id="zhihu" onclick="st(this,'40051200','zhihu')" uigs-id="nav_zhihu">知乎</a></li>
<li><a href="http://pic.sogou.com" id="pic" onclick="st(this,'40030500','pic')" uigs-id="nav_pic">圖片</a></li>
...
其中filter高階函式進行過濾時還可以使用正則來進行匹配篩選。
不過一般情況下僅僅使用selector就能比較精確的獲取結果集了,因此filter也不用寫得很複雜。