你是否每天都在網路上做重複的事情呢?像是複製貼上啦、抓圖片啦,或是一直重新整理網頁看看有沒有更新,例如購物網站中缺貨的商品捕貨了嗎?演唱會有沒有新的場次呢?
其實這些東西都可以自動化執行,方法就是撰寫爬蟲程式,這是一種用來尋找、處理網路上的文字、圖片等等的程式,也可以說是模仿使用者平常用瀏覽器做的事情的程式。爬蟲程式最普遍使用的語言是Python,而這也是我最建議用來入門程式語言的方式,因為很少有東西可以像爬蟲程式一樣,透過從網路上擷取資訊,可以直接看到程式執行的結果,而不是生硬的程式碼。
文章目錄
什麼是爬蟲程式
其實爬蟲程式做的事情跟操作瀏覽器一樣,也就是輸入網址、開啟網頁、找出你要的內容,然後重複這件事情。只不過爬蟲程式可以自動化執行這些事。

先來看看瀏覽器做了什麼事情好了。在我們平常使用瀏覽器的時候,首先會輸入或點選一個網址,接著瀏覽器會跟這個網址進行連線,連線之後就嘗試取得網頁的內容,然後再呈現在瀏覽器上。等到開好網頁之後,你就可以找你想看的資訊啦。
而爬蟲程式做的事情是一樣的,所以在撰寫程式的時候,首先要寫一個可以幫你開啟網頁的程式,接著讓程式去接收網頁,接收好之後再讓程式從裡面找出你有興趣的東西。
聽起來很複雜,不過還好透過Python的內建工具,我們可以省掉很多工作,就如同操作瀏覽器一樣簡單。
網頁的骨架:HTML
在開始寫程式之前,我們先來討論一下究竟網頁是什麼吧?現在你可以嘗試一件事,就是開啟一個網頁,在網頁空白處,點一下右鍵,看到「檢視網頁原始碼」之後按下去看看,這就是網頁本人啦。

這時候你應該會看到一堆奇怪的符號,再仔細一點看,你會發現這些符號似乎把文字、連結之類的東西包圍住了。沒錯,那些怪怪的符號就是HTML。

在討論HTML之前,我們可以先想一個問題:網頁要怎麼排版?
網頁中充滿了文字、圖片、連結…而這些東西要怎麼排版呢?這就是HTML的功用,可以告訴瀏覽器網頁要怎麼排版。如果沒有排版的話,那就會變成一堆散亂的文字。想一下文字文件和WORD檔,前者沒有排版,所有文字都擠在一起;後者可以透過排版來控制文字的顯示位置。

HTML就像是網頁的骨架,紀錄了網頁中不同類別的資訊要怎麼呈現,像是標題要放在哪呢?標題的字要多大呢?某個超連結要連到哪個網頁呢?平時操作瀏覽器的時候不會注意到HTML的出現,因為我們看到的是瀏覽器處理過後的結果。如果要寫爬蟲程式的話,就必須要能夠分析HTML。一樣透過Python的工具,可以讓我們如同操作瀏覽器一樣,從HTML中找出我們要的資訊,只不過變成用程式去尋找而已。
用爬蟲程式來抓取維基百科吧
為什麼要挑選維基百科呢?因為維基百科的網頁結構比較穩定,同時也不會阻擋爬蟲程式的操作,這些都是用維基百科當作練習網站的好理由。
在這裡我們來寫第一個爬蟲程式吧,題目很簡單,就是抓取維基百科頁面的標題就好了。如果覺得這太簡單的話,之後還會準備更多範例給大家嘗試的。

分析維基百科的網頁架構
在這裡我們先來分析一下維基百科的網頁是長怎麼樣好了,這是寫任何爬蟲程式的第一步,分析你的目標網頁。在這裡我們就從台灣美食開始啦,打開台灣料理的維基條目。
接下來就是先尋找標題「臺灣料理」到底藏在哪裡呢?這次嘗試不一樣的方法,首先按下F12按鈕,這時候你的瀏覽器右邊應該出現了一個新的頁面,接著再點擊一下Elements,這樣就可以看到HTML囉。

至於要尋找標題在哪裡有個快速的方法,按一下左上角的游標符號,然後在去點一下畫面中的標題,這樣就可以找到標題藏在哪裡囉。

這時候來分析一下標題的HTML,看起來長這樣是吧
<h1 id="firstHeading" class="firstHeading" lang="zh-Hant-TW">臺灣料理</h1>
注意這裡頭尾的h1標籤,這代表標題是使用h1的文字標示,一般來說一個網頁只有一個h1標籤,而且通常是用在標題。不過網路經常打破慣例,這也是選擇維基百科來練習的好處,比較不會出現意料之外的情況。
然後再仔細分析一下,可以看到h1的標籤是藏在這樣的結構裡:
html
-body
-div
-h1
分析出這個結構很重要,因為下一步就要寫程式了,然後你必須透過這種結構來告訴電腦你要抓取什麼東西。
不過大家應該可以看到,除了div、h1這些標籤以外,還有出現class和其他標籤,這些標籤是和HTML搭配使用的,叫做CSS。具體的用法下一篇再說吧,這些標籤可以用來做更精確的定位。
實地撰寫程式碼
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen('https://zh.wikipedia.org/wiki/%E8%87%BA%E7%81%A3%E6%96%99%E7%90%86')
bs = BeautifulSoup(html.read(), 'html.parser')
print(bs.h1)
執行這段程式碼就會得到
<h1 class=”firstHeading” id=”firstHeading” lang=”zh”>臺灣料理</h1>。
如果不想要頭尾的<h1>,那就print(bs.h1)改成print(bs.h1.text)

這段程式碼要注意一點,就是這只會輸出第一個h1標籤。如果你遇到的是不標準的網頁,具有多個h1標籤,那麼就有可能輸出不是你要的東西。
函式庫的說明
接下來就說明一下這個程式做了什麼事情。首先看到上面那兩行from開頭的程式碼,那兩行就是我前面說的工具,也就是函式庫,這可以幫助我們取得網頁。那麼這兩個函式庫到底有什麼功用呢?
打開網頁:urlopen
首先看到第一行程式碼,這段程式碼用來載入urlopen這個函式庫。
from urllib.request import urlopen
這個函式庫是從urllib裡面取得的,而這個函式庫可以做很多開啟網頁相關的事情,包含處理cookie、處理user agent等等,這些在更進階的爬蟲程式裡面很重要,而urlopen正如同名字一樣:url-open,可以用來打開網頁,取得網路上的資訊。說穿了其實就是跟平常用瀏覽器開網頁時一樣的功能。
轉換結構:BeautifulSoup
第二行程式碼引用了另一個函式庫,這個函式庫幫助我們把混亂的HTML轉換成較整齊的結構,這稱作XML。在轉換之後可以讓我們直接輸入標籤,像是h1,就直接找到指定的文字。
程式碼說明
程式碼的前兩行用來載入兩個函式庫,而接下來究竟用函式庫做了什麼事情呢?
首先看到第三行,這串程式碼告訴電腦把括號內的網頁,用urlopen打開,然後存到html裡面。在這裡你可以取其他的名字替代html。

第四行的括號內可以看到有兩個參數,在這一行我們將網路上載到的html轉換成方便尋找資料的形式。兩個參數中,第一個代表你的HTML檔案要從哪裡來?第二個代表你要用什麼程式來解析HTML檔?

在轉換成容易使用的格式之前,必須要先分析HTML的內容,而html.parser就是一個常用的解析函式。
最後一行則是從我們剛才整理好的資料裡面,取出h1這個標籤的文字。
這樣就完成了一個簡單的爬蟲程式啦。這個範例就是用來模擬平常用手去複製貼上的過程,之後會再講更複雜的應用。