Beautiful Soup — Python 的網路爬蟲套件
網路爬蟲是啥呢?簡單地說一下,網路爬蟲就是可以用程式對目標伺服器發請求,伺服器回傳後所得到的內容
通常,我們會過濾這個內容,只留下真正我們需要的資訊
舉例來說,我今天想要寫一個按看NBA比分的爬蟲,我們就找到了NBA官方網站
因為我們只是要看比分,沒有要看什麼球員資料,球隊戰績,比賽數據等等之類的,這時候儘管首頁就有比分資訊,我們還是進入比分的選單
接下來我們就可以過濾出我們需要的資訊,假設這邊我們只想要知道兩隊的比分,其他都不重要,我們可以這樣做:
我們只需要抓出
{A隊名稱:A隊得分, B隊名稱:B隊得分}
這個對應關係就可以了,如果抓了一天的戰績表,結果會變成這樣:
[
{溜馬: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 就可以抓到自己的電腦囉~