Beautiful Soup — Python 的網路爬蟲套件

Yu-Hsien Yeh
6 min readMar 22, 2018

--

網路爬蟲是啥呢?簡單地說一下,網路爬蟲就是可以用程式對目標伺服器發請求,伺服器回傳後所得到的內容

通常,我們會過濾這個內容,只留下真正我們需要的資訊

舉例來說,我今天想要寫一個按看NBA比分的爬蟲,我們就找到了NBA官方網站

因為我們只是要看比分,沒有要看什麼球員資料,球隊戰績,比賽數據等等之類的,這時候儘管首頁就有比分資訊,我們還是進入比分的選單

接下來我們就可以過濾出我們需要的資訊,假設這邊我們只想要知道兩隊的比分,其他都不重要,我們可以這樣做:

我們只需要抓出

{A隊名稱:A隊得分, B隊名稱:B隊得分}

這個對應關係就可以了,如果抓了一天的戰績表,結果會變成這樣:

(這個表格是google提供的,非NBA官方網站)
[
{溜馬:110, 湖人:100},
{騎士:124, 公鹿:117},
{76人:108, 黃蜂:94},
{籃網:118, 灰熊:115},
{熱火:149, 金塊:141},
{尼克:110, 公牛:92},
{馬刺:89, 勇士:75},
{國王:90, 活塞:106},
]

那重點是我們要如何知道要抓哪個東西代表球隊名稱,哪個東西又代表球隊得分呢?

實作

最一般的使用方式為find()以及find_all():

a_soup = soup.find('tag_name', class_='class_name')
b_soup = soup.find_all('tag_name', class_='class_name')

以上面的例子來看a_soup是一個Tag物件,可能會長這樣:

<tag_name>

</tag_name>

b_soup則會是一個陣列,陣列裡面的元素都會跟a_soup一樣都是Tag物件

[
<tag_name>…</tag_name>,
<tag_name>…</tag_name>,

]

class_是保留字,用來選取element的class attribute。但是element的attribute往往也可以讓使用者自己定義,所以bs4也有提供選取自訂attribute的方法,需在find()再加一個參數attrs,方法如下:

attrs = {attribute_key: attribute_value}

那如果是想要知道這個tag 有沒有某個attribute呢?請使用get()

tag.get('attribute_name')

像是劍橋英語字典網站reciprocity 這個字有三個tab可以選擇:
英式英語
商用英語
例句

british = tabEntry.find(‘div’, class_=’tabs__content on’, attrs={‘data-tab’: ‘ds-british’})business = tabEntry.find(‘div’, class_=’tabs__content on’, attrs={‘data-tab’: ‘ds-business-english’})example = tabEntry.find(‘div’, class_=’tabs__content on’, attrs={‘data-tab’: ‘ds-example’})

如此一來我們就可以抓到自己想要的tab了 \@@/

如果想要拜訪tag的子節點,可以使用 tag.contents 和 tag.children 這兩個方法,差別在於 contents 會回傳一個 list,children 則會回傳一個 iterator

這兩個方法都只能拜訪第一層的子節點,如果要拜訪孫節點,請使用tag.descendants,descendants也是產生一個 iterator

tag定位之後,我們就可以更進一步想要抓自己想要的資訊,在我之前的專案裡面因為是要製作成單字卡,所以需要的東西就是文字音檔

文字的話可以使用:

tag.get_text()

它會將目標tag裡面的所有文字都擷取出來

也可以使用:

tag.find_all(text = True)

它的回傳值是一個陣列,好處是不會像get_text()一樣把字串都黏在一起

<< get_text() >> : 
I linked to example.comabc123
lalala123
<< find_all(text=True) >> : [‘\nI linked to ‘, ‘example.com’, ‘abc123’, ‘\n’, ‘lalala’, ‘123’]

音檔的話我都使用:

urllib.request.urlretrieve(requestUrl, download_directory)

這是日文字典網站 jisho.org
音檔通常都要給使用者聽發音,所以都會有超連結
在element中都以<a>…</a>的形式存在

如此這般,我們可以用上述的方法找到這個音檔的網址,再用 urllib.request.urlretrieve 就可以抓到自己的電腦囉~

--

--