這次我想爬取 majortests 中的英文列表。這個網站的組成蠻簡單的(雖然廣告很多),標籤也很一致整齊,很適合做為爬取單字的爬蟲練習。此為我的 github page 上 2021 年 2 月搬運過來之文章,並且有做一些語句上的修正。
前置作業-觀察
在爬網頁之前,要先觀察網頁的結構。這個網頁中的單字表有分 10 個單元,目的是把這幾個單字表的單字都通通抓取下來,因此我們會需要這 10 個單字表的網址。

實際查看後發現,這幾個單字表的網址變化蠻規律且簡單的:
從 https://www.majortests.com/word-lists/word-list-01.html 一直到 https://www.majortests.com/word-lists/word-list-10.html ,能夠藉由更改 word-list- 後方的數字達到造訪每個單字表的目的。
另外單字表在 html 標籤中的位置,對照實際的單字表,可以觀察到單字表在 table 標籤中,它們的 class 都是 wordlist,而單字本身和解釋,分別在 tr 標籤中用 th 和 td 隔開,是一個很整齊的結構,爬起來不會太麻煩。


功能
接著思考爬蟲,有幾項基本的功能要設計:
- 生成網址
- 改變 header
- 獲取網頁 tag 結構
- 抓取單字
- 爬蟲
- 存成 csv 格式
要 import 的有:
from bs4 import BeautifulSoup import time import csv import requests
生成網址
因為標號是 01, 02, ….,09,雖有十個單字表,但這裡主要想實作爬蟲,因此將過程再弄得更簡單易點,這次我們先只抓取 9 個單字表。URL = "https://www.majortests.com/word-lists/word-list-0{0}.html"
設一個陣列 urls,用迴圈生成編號從 1 到 9 的網址,並將生成的網址放進裡面。
def generate_urls(url, start, end):
urls = []
for i in range(start, end + 1):
urls.append(url.format(i))
return urls
改變 header
網站有可能會發現有奇怪的東西(例如一個 Python 程式)在拋出請求,為了不讓網站發現,需要一個 function 去將 header 更改成瀏覽器的樣子。
網路上查會發現有很多不同的寫法,複製任何一種查得到的 header 都可以,只要能順利讓網站接受即可。
def change_get(url):
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
'AppleWebKit/537.36 (KHTML, like Gecko)'
'Chrome/63.0.3239.132 Safari/537.36'}
return requests.get(url, headers = headers)
獲取網頁 tag 結構
這裡沒什麼特別的,僅是把 html 結構抓下來。
def get_html(str):
return BeautifulSoup(str, "lxml")
抓取單字
接下來進入到重點部分,如何抓取單字。開始利用 BeautifulSoup 所獲得的 tag 結構,去挖需要的東西。先前我們已經分析過結構了,由於它們的 class 都是 wordlist,本身很好鎖定,使用 find_all() 抓取。再來單字、解釋們分別在 tr 中的 th 和 td 標籤內。
def get_words(soup, file):
words = []
count = 0
for table in soup.find_all(class_ = "wordlist"):
count += 1
for word_entry in table.find_all("tr"):
newWord = []
newWord.append(file)
newWord.append("Group " + str(count))
newWord.append(word_entry.th.text)
newWord.append(word_entry.td.text)
words.append(newWord)
return words
爬蟲
解決完單字處理後,來寫一小段簡單的爬蟲。利用以上的 function,將所要爬的網址改變 header 後,取得該網站結構,並且利用這個結構去找自己要的 tag,並儲存單字在自己設的陣列裡面。
def web_scraping(urls):
eng_words = []
for url in urls:
file = url.split("/")[-1].split(".")[-2].replace('-', ' ') #利用 url 字串改成檔案來源名稱
print("scrape the file : " + file)
r = change_get(url)
if r.status_code == requests.codes.ok:
soup = get_html(r.text) #取得 html 字串
words = get_words(soup, file) #html 字串的處理
eng_words = eng_words + words
print("wait for 5 seconds...")
time.sleep(5)
else:
print("HTTP requests error")
return eng_words
存成 csv 格式
上方差不多把事情做完了,記得將結果印出或是存成一個檔案。這裡就是採用先前存好的 file 和 words,逐一寫入檔案內。
def to_csv(words, file):
with open(file, "w+", newline = "", encoding = "utf-8") as fp:
writer = csv.writer(fp)
for word in words:
writer.writerow(word)
最終主程式呼叫
if __name__ == "__main__":
urls = generate_urls(URL, 1, 9)
eng_words = web_scraping(urls)
for item in eng_words:
print(item)
to_csv(eng_words, "words.csv")
當然要看一下執行結果囉:

結果抓完後發現有很多不會的單字QQ








