貼近生活的上網自動化
requests
selenium
林承諺
我從小就有一個夢想 : 開遊戲外掛
我摸索了好幾年,沒想過是要用到【網路爬蟲】這個領域
或許這聽起來很陌生 很困難
但這讓我實現了一個從小的夢想
也是他,開啟了我對程式的興趣
班級自主學習發表 - 票選第一
好評率百分百
2025 高一下全校自主學習發表
2025 高一下全校自主學習發表
發表內容
這堂課能帶給你甚麼
拿到天氣資料
遊戲外掛
搶票系統
QR CODE
每天都重複?
好無聊 !
AUTO
讓電腦自動完成日常瑣事
定義
用程式模擬人類在網路上的行為
是怎麼做的?
抓取資料 (GET)
傳送資料 (POST)
常用的有3種模式
自動點擊
就像你上網找歌單
網路爬蟲
你啟動它
輸出
進入kkbox
找到資料
記下來
進入kkbox
找到資料
記下來
抓取資料GET範例
想找歌單? 按一下就好
進入kkbox
找到資料
記下來
而且程式不會分心滑到其他地方
傳送資料POST範例
就像你填春遊報名表
進入表單
填寫資料
送出
網路爬蟲
你啟動它
輸出ok
進入表單
準備資料
送到伺服器
想去春遊? 按一下就好
而且程式可以一秒送出很多表單
進入表單
準備資料
送到伺服器
用途:
看得到的網頁,理論上都可以「爬」
| 語法 | 優點 | 套件 |
|---|---|---|
| Python | 易學,初學者首選 | requests BeautifulSoup Selenium |
| JavaScript | 模擬網頁行為,能抓取動態資料 | axios, cheerio |
| Java | 穩定,適合大量處理 | Jsoup, Selenium |
| C# | 整合Windows系統 | HtmlAgilityPack |
Python ✅
入門最快
只要語言能發 request、能處理 HTML,就能寫爬蟲
但
網路爬蟲三大套件
直接發送請求
整理接收結果
模擬真實使用者
| 類型 | 用途 | 特色 |
|---|---|---|
| requests + BeautifulSoup | 靜態網頁 | 直接抓下整個網頁的原始碼 |
| Selenium | 動態網頁 | 模擬人類操作,可取得動態數值 |
| API爬蟲 | 伺服器端口 | 官方資料接口、回傳指定資料 |
在後面都會教到
pip install requests
# PRESENTING CODE
# PRESENTING CODE
import requests# PRESENTING CODE
url = "https://ckcsc.net/"
data = {"key": "example"}
response = requests.get(url)
response = requests.post(url, json=data)有兩種?
GET? POST?
# PRESENTING CODE
| 屬性 | 用途 | 範例 |
|---|---|---|
| requests.get | 向伺服器【請求】資料 | 瀏覽網頁 |
| request.post | 向伺服器【發送】資料 | 提交表單 |
透過瀏覽器互動
平時上網
取得網頁的原始碼
發送取得網頁的請求
回復請求資料
網路爬蟲
# PRESENTING CODE
import requests
a = requests.get("https://ckcsc.net")
print(a)賦值
使用模組
使用GET
要取得的網址
執行看看?
# PRESENTING CODE
import requests
a = requests.get("https://ckcsc.net")
print(a)輸出的是200,怎麼不是整個網站?
<Response [200]>直接print,預設會顯示 HTTP 回應
【狀態碼】
| 數字 | 英文顯示 | 中文意義 |
|---|---|---|
| 200 | OK | 請求成功 |
| 404 | Not Found | 請求的資源不存在 |
| 500 | Internal Server Error | 伺服器內部發生錯誤 |
快速得知請求的成功與否
# PRESENTING CODE
import requests
a = requests.get("https://ckcsc.net")
print(a.text)讓它輸出網站的整個內容
輸出【文字屬性】
輸出結果
看的出來成電社網大部分都是JavaScript動態生成
# PRESENTING CODE
import requests
a = requests.get("https://tw.yahoo.com/")
print(a.text)換成爬取雅虎奇摩的首頁試試看
輸出結果
Edge: Too Many Requests<Response [429]>.text
Why?
沒有出現網站而是出現錯誤?
常見的手段:
✔️偽裝成正常的瀏覽器
✔️不要告訴他你是Python
❗新增 User-Agent
常見的請求 Header,用於識別發送請求的應用程式
不告訴你
我是Python,請求網頁
就像是你的電腦的身分證,伺服器會接收到
給你html
我是Mozilla/5.0 (Windows NT 10.0; Win64; x64),請求網頁
1.
2.
檢查
network
3.
4.
重新整理
隨便點一樣請求
5.
往下滑,會找到User-Agent
# PRESENTING CODE
import requests
Useragent = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
a = requests.get("https://tw.yahoo.com/", headers=Useragent)
print(a.text)實作User-Agent
將User-Agent以字典形式儲存並附在括號中,參數名稱header後面
把電腦的身分證附在請求裡面
# PRESENTING CODE
import requests
Useragent = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
a = requests.get("https://tw.yahoo.com/", headers=Useragent)
print(a.text)import requests
a = requests.get("https://tw.yahoo.com/")
print(a.text)原本的
# PRESENTING CODE
輸出結果
成功回傳整個網頁
看到新聞 :
# PRESENTING CODE
import requests
url = "https://httpbin.org/delay/5"
Useragent = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get(url, headers=Useragent)
print(response.text)實測看看這個網站
拖了好久才輸出
實測 !
# PRESENTING CODE
import requests
url = "https://httpbin.org/delay/5"
Useragent = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get(url, headers=Useragent)
print(response.text)設定延遲5秒才輸出
✔️讓程式適可而止,適時放棄
❗新增 timeout
✔️像是抓取跑很慢的網站
# PRESENTING CODE
response = requests.get(url, timeout=5)基本語法:
設定等待不超過5秒
# PRESENTING CODE
import requests
url = "https://httpbin.org/delay/5"
try:
response = requests.get(url, timeout=3)
print(f"發送成功")
print(response.text)
except: #如果沒成功執行則報錯
print("伺服器在3秒內沒有回應")實際演練:
伺服器在3秒內沒有回應在嘗試3秒後就會放棄
只能在指定秒數內執行完成,否則就會報錯
抓取台北市政府官網,要使用User-Agent並在嘗試最多3秒後放棄
# PRESENTING CODE
import requests
Useragent = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
try:
a = requests.get("https://www.gov.taipei/", headers=Useragent,timeout=3)
print(a.text)
except:
print("伺服器在3秒內沒有回應")# PRESENTING CODE
可以看到蔣萬安最近做了甚麼
cookies
proxiex
郵差
( API )
寄信者
( 使用者 )
面試官
( 伺服器 )
寄信
傳送
傳送
送回
✅填地址和郵遞區號
✅填面試官要的個資
❌知道怎麼送信
❌知道面試官怎麼審核
乖乖在家就會送回來 不用懂
你只需要知道✅
你不需要知❌
底層系統細節: 哪種程式語言、資料庫結構、演算法等。
系統基礎架構: 部署在哪裡、使用了哪些伺服器、網路拓撲結構等
版本細節:只要 API 的介面保持向後兼容,我們通常不需要深入了解目標系統的具體版本號和內部更新細節。
輕鬆易懂
抓取空氣品質指標
不使用API
使用API
使用他「專門提供做這件事的連結」 ,取得整理好的資料
https://data.moenv.gov.tw/api/v2/aqx_p_432?api_key=9b651a1b-0732-418e-b4e9-e784417cadef&limit=1000&sort=ImportDate%20desc&format=JSON"
# PRESENTING CODE
import requests
url = "https://data.moenv.gov.tw/api/v2/aqx_p_432?api_key=9b651a1b-0732-418e-b4e9-e784417cadef&limit=1000&sort=ImportDate%20desc&format=JSON"
Useragent = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get(url, headers=Useragent)
print(response.text)輸出:
# PRESENTING CODE
我是樹林人
❓Python看不懂
✔️轉換成Python字典格式
❗使用.JSON解碼
語法:
response = (requests.get(url, headers=Useragent)).json()在回傳後的資料加上.json()
注意事項:只有格式為json時才會運作,否則會報錯
# PRESENTING CODE
import requests
url = "https://data.moenv.gov.tw/api/v2/aqx_p_432?api_key=9b651a1b-0732-418e-b4e9-e784417cadef&limit=1000&sort=ImportDate%20desc&format=JSON"
Useragent = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = (requests.get(url, headers=Useragent)).json()
print(response)輸出:
✅輸出Python字典格式
❓轉換成字典之後,如何取得其中的數值?
✔️直接取得字典內的數值
❗使用KEY處理巢狀結構
ex.取得pm10=多少?
# PRESENTING CODE
data = {
'status': 'success',
'result': {
'user': {
'id': 123,
'profile': {
'name': 'Alice',
'age': 30,
'address': {
'city': 'Taipei',
'zipcode': '100'
}
},
'hobbies': ['reading', 'coding']
}
}
}
user_id = data['result']['user']['id']
print(user_id)基本語法
依序取得鍵中的鑑中的值
data['result'] -> {'user': ...}
data['result']['user'] -> {'id': 123, 'profile': ...}
data['result']['user']['id'] -> 123# PRESENTING CODE
import requests
import json
url = "https://data.moenv.gov.tw/api/v2/aqx_p_432?api_key=9b651a1b-0732-418e-b4e9-e784417cadef&limit=1000&sort=ImportDate%20desc&format=JSON"
Useragent = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get(url, headers=Useragent)
data = response.json()
for record in data['records']:
if record['sitename'] == '屏東':
print(record['pm10'])30❓想取得那種資料怎麼辦
✔️自己找&直接get讓他回傳
ex.網頁遊戲的個人資料頁面
1.
2.
檢查
network
3.點擊會取得資料的物件
ex.按下頭像會跳出資料
4.你會看到一個.json,點進去
API在此
這是使用post,會在下個章節說明
5.
回傳的內容
此時就可以透過解析巢狀結構來獲取想要的資料
去教育部抓取編號為353302的學校名稱
# PRESENTING CODE
import requests
a = requests.get("https://stats.moe.gov.tw/files/school/114/high.json").json()
for i in a:
if i['代碼'] == "353302":
print(i['學校名稱'])用for迴圈遍歷,如果代碼為353302
就印出"學校名稱"
市立成功中學
| 屬性 | 用途 | 範例 |
|---|---|---|
| requests.get | 向伺服器【請求】資料 | 瀏覽網頁 |
| request.post | 向伺服器【發送】資料 | 提交表單 |
剛剛get ➡️ 他提交給我們
現在post ➡️ 我提交給他們
透過瀏覽器互動
平時上網
資料傳送
回復結果
發送我們的資料
回復【我收到了】
網路爬蟲
通常用於:
# PRESENTING CODE
url = "https://XXX.com/api/sign_in"
response = requests.post(url, data=data)基本語法
用POST
要發送的資料
要發送到哪個網址?哪個網址會接收帳密?
傳到首頁 Yahoo奇摩 ?
❌
✔️傳到接收帳密的API
不同API處理不同收到的資料
你要先【找到發送到哪】
而每個位置有不同的網址
處理登入
處理攻擊
處理好友
ex.登入要發送到
https://www.XXXXX.com/api/sign_in
修改個資要發送到
https://www.XXXXX.com/api/user_settings
前面講過,使相同方式尋找API 並 post出去
1.點擊會發送資料的物件
ex.按下登入會送出密碼
POST帳密出去
API在此
payload 發送出去的資料(帳密)
2.查看帳密發送到哪了
response 伺服器回復(是否登入成功)
payload ➡️ 發送出去的資料
3.查看發送了甚麼
response 伺服器回復(是否登入成功)
ok表示成功
可知發送出去的是一個json格式
# PRESENTING CODE
import requests
url = "https://www.pagamo.org/api/sign_in"
data = {
'account': 'wallace999999',
'encrypted': True,
'password': 'SQ3GcclkDIlmMulkfdpnUxSO1FssO0RBLPfrmFT5x2DuteYMSRr2luPaYJywYXRpLclcOckosmHWURjTYdIHMYFPTtZ3VT6WHNz+9p4hpf94NAAtKIic6tQn0uuI2B2PBGCMg88ZJ77CB8yqGumt/T5+ZbaueHHn42OWzCE1h6Xo8fSsRZnrQMXRkUwLbRojZ6FTa2yTcGMwblOia7ohULM/sDvOYXTXX8oMCSChvbUcXcpszmgegdnKj7KRmkOLuEYX3LcZjY1c34B70R8HYhBsWZnLjdxHC7f70OfcKplnWOPHpOPIy8+SMATJoBF4Eq1/jvPduaf8W4PfucXKzA=='
}
Useragent = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.post(url, data=data, headers=Useragent)
print(response.text)要發送的網址
發送的資料
發送到【接收帳密的端口】
語法範例 : 登入
反反爬蟲
# PRESENTING CODE
系統回復: 會自轉化成Python字典
剛剛的網頁回復:
✔️資料相同
範例:遊戲外掛
自動開PaGamO的【假期模式】
事實上,只是POST到API兩個小數字而已
事實上,只是POST到API兩個小數字而已
✔️相同效果
# PRESENTING CODE
import requests
info_url = 'https://www.pagamo.org/users/personal_information.json'
s = requests.Session()
def open_hoilday():
#登入
login_url = 'https://www.pagamo.org/api/sign_in'
login_data = {'account': "wallace999999", 'encrypted': True, 'password': "SQ3GcclkDIlmMulkfdpnUxSO1FssO0RBLPfrmFT5x2DuteYMSRr2luPaYJywYXRpLclcOckosmHWURjTYdIHMYFPTtZ3VT6WHNz+9p4hpf94NAAtKIic6tQn0uuI2B2PBGCMg88ZJ77CB8yqGumt/T5+ZbaueHHn42OWzCE1h6Xo8fSsRZnrQMXRkUwLbRojZ6FTa2yTcGMwblOia7ohULM/sDvOYXTXX8oMCSChvbUcXcpszmgegdnKj7KRmkOLuEYX3LcZjY1c34B70R8HYhBsWZnLjdxHC7f70OfcKplnWOPHpOPIy8+SMATJoBF4Eq1/jvPduaf8W4PfucXKzA=="}
Useragent = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
print('正在登入...')
login_resp = s.post(login_url, data=login_data, headers=Useragent).json()
gc_id = login_resp['data']['gtm_info']['gc_id']
print(gc_id)
headers = { "Origin": "https://www.pagamo.org", "Referer": f"https://www.pagamo.org/map?course_code=TMGQOQS7" ,"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"} # 將數據以JSON格式傳遞
# 發送POST請求
response = s.post("https://www.pagamo.org/gamecharacters/holiday_mode", json={'gc_check': gc_id, 'key': gc_id}, headers=headers)
print(response.text)
open_hoilday()範例程式碼:
登入
POST到holiday(假期模式)
對https://httpbin.org/post發送一組帳號密碼,觀察他的回應
提示: 可以透過前面簡報範例進行修改
# PRESENTING CODE
import requests
data = {'username': 'wallace999999', 'password': '12345678'}
response = requests.post('https://httpbin.org/post', data=data)
print(response.text){
"args": {},
"data": "",
"files": {},
"form": {
"password": "12345678",
"username": "wallace999999"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Content-Length": "40",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.32.3",
"X-Amzn-Trace-Id": "Root=1-6807af2e-736618625aab73be70d21e72"
},
"json": null,
"origin": "111.249.209.22",
"url": "https://httpbin.org/post"
}會把你發送的東西傳回來,代表他有收到
{
"args": {},
"data": "",
"files": {},
"form": {
"password": "12345678",
"username": "wallace999999"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Content-Length": "40",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.32.3",
"X-Amzn-Trace-Id": "Root=1-6807af2e-736618625aab73be70d21e72"
},
"json": null,
"origin": "111.249.209.22",
"url": "https://httpbin.org/post"
}會把你發送的東西傳回來,代表他有收到
蝦?什麼網站會做這種蠢事情?把你傳回來?
https://httpbin.org
但至少你現在學會POST了
# PRESENTING CODE
✔️有
❗httpbin.org
由 Python 的 Flask 框架建構
主要用途:讓開發者測試 HTTP 請求與回應
測試不同 HTTP 請求:
GET, POST, PUT, DELETE, PATCH, OPTIONS
檢視回傳的資料格式 / headers
模擬伺服器回應,例如:
模擬延遲 (/delay)
模擬錯誤 (/status/404)
回傳指定的 JSON (/json)
⬅️剛剛出現的
⬅️測試是否會崩潰
⬅️前面出現的 抓取個資
模擬各種端口
各種類型爬蟲都可以試
放在公開的網路平台上,讓你自己也可以使用
提供啟動方法:
路上有交通規則
爬蟲也有行為規範
存放於網站的根目錄下
ex.
https://www.xxxxx.com/robots.txt因為他只是一份文件,不具強制力,惡意爬蟲可能會無視
語法簡介
# 符號/ 開頭* 語法簡介
禁止所有爬蟲存取整個網站:
禁止特定爬蟲存取特定目錄:
允許特定爬蟲存取特定目錄:
User-agent: *
Disallow: /User-agent: BadBot
Disallow: /secret/User-agent: GoodBot
Allow: /public/
Disallow: /# PRESENTING CODE
語法簡介
User-agent: 指定適用於哪些爬蟲Disallow: 禁止爬蟲存取的路徑或目錄Allow: 允許爬蟲存取的路徑或目錄User-agent: GoodBot
Allow: /public/
Disallow: /ex.
特別允許某一個
抓取Yahoo網站的robots.txt,分析那些不被允許抓取
# PRESENTING CODE
不被允許:
Disallow: /p/
Disallow: /r/
Disallow: /bin/
Disallow: /includes/
Disallow: /blank.html
Disallow: /_td_api
Disallow: /_td-hl
Disallow: /_tdpp_api
Disallow: /_remote
Disallow: /_multiremote
Disallow: /_tdhl_api
Disallow: /_td_remote
Disallow: /_tdpp_remote
Disallow: /sdarla
Disallow: /digest
Disallow: /tdv2_fp
Disallow: /tdv2_mtls_fp
Disallow: /*?bcmt=*
Disallow: /tw_ms
Disallow: /nel_ms/可見他不允許我們抓取許多頁面
所以我們在沒有「偽裝」的時候進不去
接下來會換一個全新的東西
如果剛剛聽不懂的,現在可以重新認真聽了
⚡⚡⚡
設定一個位置,自動幫你點擊
點擊精靈
1 2 3
4 5
點擊1號按鈕一種網頁自動化瀏覽工具
它會自動開啟瀏覽器
模擬使用者操作:點擊、輸入、滾動等
缺點: 限用於網頁、瀏覽器
你可以把它想像成網軍 或像這樣
跟剛剛學的request有何差別?
| requests | selenium | |
|---|---|---|
| 角色 | 快遞員 | 機器人 |
| 運作方式 | 直接到伺服器門口,拿到包裹(資料或網頁)就走,整個傳給你 | 坐在電腦前,打開瀏覽器,模仿人類的點擊、輸入等所有操作 |
| 速度 | 快 (只需處理資料) | 慢 (要開啟瀏覽器) |
| 主要用途 | 獲取數據:呼叫 API、抓取靜態網頁內容 | 自動化操作:自動登入、填表單、玩遊戲 |
| 反爬蟲 | 低 (用User-Agent) | 高 (本來就像真人) |
自動登入網站、填寫表單、搶票
無法用 API 抓取數據的地方(ex.社交媒體水軍自動操作)
實際範例: 網路上的搶票系統
裡面的程式碼?
就是用Selenium
再來一個範例
是用Selenium
準備好來學這個酷東西了嗎 ?
pip install selenium# PRESENTING CODE
# PRESENTING CODE
import selenium使用selenium需要使用專用的瀏覽器 chrome driver
步驟1: 前往「設定→關於chrome」記下自己的chrome版本型號
(在第一行)
步驟2: 前往 https://googlechromelabs.github.io/chrome-for-testing/
下載與自己相同版本的chrome driver型號
範例: 假設我的型號是139.0.7258.155
將win64版的連結複製貼上到瀏覽器
End.