【Python 網路爬蟲筆記】Requests Library - part 2

感謝你點進本篇文章!!我是 LukeTseng,一個熱愛資訊的無名創作者,由於近期大學開設大數據分析程式設計這門課程,裡面談到了爬蟲概念,讓我激起一些興趣,因而製作本系列筆記。

聲明:本篇筆記僅供個人學習用途,斟酌參考。

另外本篇筆記使用 VSCode 環境進行編寫,部分模組(函式庫)需自行下載。

安裝 Requests 函式庫

Colab 及 Anaconda 環境無須安裝,內建即有。

若不確定自己有裝的話,可以輸入 pip list 查看已安裝的所有模組。

使用指令 pip install requests

pip_list

像我已經安裝過了,再安裝一次他會跟你說 Requirement already satisfied,表示你裝過了。

pip_install_requests

另外一個測試有沒有安裝過該模組的方法,可以打開 VSCode 或其他環境,輸入以下指令並執行即可:

1
2
import requests
print(requests.__version__)

執行後會在最下面出現版本資訊。

vscode_example

Requests 基礎用法

使用前須引入模組 import requests

from requests import * 之後就免在 method 前面打上繁瑣的 requests。

先來看個表:

Methods敘述
get(url, params, args)向指定 URL 發送 GET 請求
post(url, data, json, args)向指定 URL 發送 POST 請求
put(url, data, args)向指定 URL 發送 PUT 請求(將新資料取代目標資源)
delete(url, args)向指定 URL 發送 DELETE 請求
head(url, args)向指定 URL 發送 HEAD 請求(僅取得 Headers 資訊,沒有 Body)
patch(url, data, args)向指定 URL 發送 PATCH 請求
request(method, url, args)向指定 URL 發送指定方法的請求

table from W3Schools:https://www.w3schools.com/python/module_requests.asp

我們先從最簡單的 get 請求開始做起,範例網址:https://luketsengtw.github.io/

1
2
3
4
5
6
7
import requests

url = 'https://luketsengtw.github.io/'

response = requests.get(url)

print(response)

Output:

1
<Response [200]>

最後輸出了 <Response [200]>,這個 200 是 Status Code,表示網站運作正常的意思。

那我們可以在後綴加上 .text 看看輸出的內容會是怎樣:

1
2
3
4
5
6
7
import requests

url = 'https://luketsengtw.github.io/'

response = requests.get(url)

print(response.text) # modify

Output:

image

答案就是一長串,超級多的 HTML 內碼 XD。然後我們就成功爬取到這個網站的 HTML 資訊了。

像剛剛的 Status Code 也可以寫成方法單獨輸出(.status_code):

1
2
3
4
5
6
7
import requests

url = 'https://luketsengtw.github.io/'

response = requests.get(url)

print(response.status_code)

Output:

1
200

既然講到了 .status_code 以及 .text,那我們就列個完整表給這些 Response 方法吧:

Methods敘述
.headers回傳 response headers 的字典
.encoding回傳用於解碼 response.content 的編碼
.elapsed回傳一個 timedelta 物件,其中包含從發送請求到回應到達所經過的時間
.close()關閉與伺服器的連線
.content以位元組(bytes)為單位回傳回應的內容
.cookies回傳一個 CookieJar 物件,其中包含從伺服器發回的 cookie
.history回傳儲存請求(URL)歷史記錄的回應物件列表
.is_permanent_redirect如果回應是永久重新導向的 url,則回傳 True,否則回傳 False
.is_redirect如果回應被重新導向,則回傳 True,否則回傳 False
.json()回傳結果的 JSON 物件(如果結果是以 JSON 格式寫入的,如果不是則會引發錯誤)
.url回傳回應的 URL
.text以 unicode 格式回傳回應的內容
.request回傳請求此回應的請求物件
.reason回傳與 status code 對應的文字
.ok如果 status code < 400 且 >= 200,則回傳 True;否則,回傳 False
.links回傳 headers 連結

table from GeeksForGeeks:https://www.geeksforgeeks.org/python/python-requests-tutorial/

POST 發送

POST 請求方法類似於新增、更新操作,會隱密傳送資料給指定的資源。

註:https://httpbin.org/post 這個網址是用於測試用的。

1
2
3
4
5
6
import requests

# 發送基本 POST 請求
response = requests.post('https://httpbin.org/post', data={'key': 'value'})
print(f"狀態碼: {response.status_code}")
print(f"響應內容: {response.text}")

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
狀態碼: 200
響應內容: {
"args": {},
"data": "",
"files": {},
"form": {
"key": "value"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, zstd",
"Content-Length": "9",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.32.5",
"X-Amzn-Trace-Id": "Root=1-68cf7a42-667a646642bff88525ef3450"
},
"json": null,
"origin": "180.176.79.173",
"url": "https://httpbin.org/post"
}

上述方式帶了一個參數 data={'key' : 'value'},用 POST 請求方法發送給 https://httpbin.org/post 這個網址。

從響應內容中可以看到有我們剛剛輸入的參數:

1
2
3
"form": {
"key": "value"
},

POST 提交表單:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests

# 表單資料
form_data = {
'username': 'XXX',
'password': 'thisismypassword',
'email': 'xxx@example.com'
}

# 發送表單資料
response = requests.post('https://httpbin.org/post', data=form_data)

# 檢查結果
if response.status_code == 200:
print("表單提交成功!")
print(response.text)
else:
print(f"請求失敗,狀態碼: {response.status_code}")

Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
表單提交成功!
{
"args": {},
"data": "",
"files": {},
"form": {
"email": "xxx@example.com",
"password": "thisismypassword",
"username": "XXX"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, zstd",
"Content-Length": "62",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.32.5",
"X-Amzn-Trace-Id": "Root=1-68cf7be7-1dc37d90043a6d9606ce14bc"
},
"json": null,
"origin": "180.176.79.173",
"url": "https://httpbin.org/post"
}

避免亂碼

透過網站的標籤 <meta charset="UTF-8"> 可以得知是使用何種編碼,這邊以我的個人網站做測試:https://luketsengtw.github.io/

如果亂碼可以先透過檢查工具查看是使用何種編碼,並使用方法 .encoding 去換編碼。

範例:

1
2
3
4
import requests
response = requests.get('https://luketsengtw.github.io/')
response.encoding = 'utf-8' # modify
print(response.text)

API 爬取開放式資料

(政府資料開放平台)以下範例使用「YouBike2.0臺北市公共自行車即時資訊」進行爬取:https://data.gov.tw/dataset/137993

JSON 連結:https://tcgbusfs.blob.core.windows.net/dotapp/youbike/v2/youbike_immediate.json

1
2
3
import requests
response = requests.get('https://tcgbusfs.blob.core.windows.net/dotapp/youbike/v2/youbike_immediate.json')
print(response.json())

Output:

image

HTTP 狀態碼

以下列了幾種常見的 HTTP 狀態碼(status code):

status code敘述
200OK / 網頁狀態正常(OK / Success)
301永久重新導向(網頁搬家)(Permanent Redirect)
302暫時性重新導向(Temporary Redirect)
400錯誤請求(Bad Request)
401未授權(Unauthorized Error)
403沒有權限進入(Forbidden)
404找不到網站(Not Found)
500內部伺服器錯誤(Internal Server Error)
504伺服器沒有回應(Gateway Timeout)

詳細請見:https://zh.wikipedia.org/zh-tw/HTTP%E7%8A%B6%E6%80%81%E7%A0%81

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests

response = requests.get('https://httpbin.org/get')

statusCode = response.status_code

print(f'Status Code : {statusCode}')

if statusCode == 200:
print('Success to request')
print(f'Content : {response.text[:100]}...')
elif statusCode == 404:
print('Not Found')
elif statusCode >= 500:
print('Server Error')

Output:

1
2
3
4
5
6
7
Status Code : 200
Success to request
Content : {
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, zstd", ...

總結

HTTP 請求方法

  • GET:
    • GET 是最常用的 HTTP 方法,用於從伺服器獲取資料。
    • 基本語法:requests.get(url),回傳的 Response 物件包含狀態碼內容
    • 如:請求網頁時會得到 <Response [200]>,其中 200 表示請求成功。
  • POST:
    • POST 方法用於向伺服器傳送資料,常用於表單提交API 呼叫
    • 可用 data 參數傳送表單資料,或 json 參數傳送 JSON 格式資料。
    • POST 請求會將資料隱密地傳送給指定資源,適合用於新增或更新操作。

Response 物件屬性及方法

Methods敘述
.headers回傳 response headers 的字典
.encoding回傳用於解碼 response.content 的編碼
.elapsed回傳一個 timedelta 物件,其中包含從發送請求到回應到達所經過的時間
.close()關閉與伺服器的連線
.content以位元組(bytes)為單位回傳回應的內容
.cookies回傳一個 CookieJar 物件,其中包含從伺服器發回的 cookie
.history回傳儲存請求(URL)歷史記錄的回應物件列表
.is_permanent_redirect如果回應是永久重新導向的 url,則回傳 True,否則回傳 False
.is_redirect如果回應被重新導向,則回傳 True,否則回傳 False
.json()回傳結果的 JSON 物件(如果結果是以 JSON 格式寫入的,如果不是則會引發錯誤)
.url回傳回應的 URL
.text以 unicode 格式回傳回應的內容
.request回傳請求此回應的請求物件
.reason回傳與 status code 對應的文字
.ok如果 status code < 400 且 >= 200,則回傳 True;否則,回傳 False
.links回傳 headers 連結

編碼處理

網頁爬取時常遇到編碼問題(可能出現亂碼),可透過檢查網頁 HTML 的 <meta charset> 標籤確認編碼格式。

使用 response.encoding = 'utf-8' 可手動設定編碼,避免中文亂碼問題。

API 資料爬取

Requests 非常適合爬取開放式 API 資料。

以政府資料開放平台為例,其可直接請求 JSON API 端點,使用 response.json() 方法將回應轉換為 Python 字典格式,便於後續資料處理和分析。

HTTP 狀態碼

HTTP 狀態碼(Status Code)為三位數字,用於指示請求(Requests)結果,常見的如下:

status code敘述
200OK / 網頁狀態正常(OK / Success)
301永久重新導向(網頁搬家)(Permanent Redirect)
302暫時性重新導向(Temporary Redirect)
400錯誤請求(Bad Request)
401未授權(Unauthorized Error)
403沒有權限進入(Forbidden)
404找不到網站(Not Found)
500內部伺服器錯誤(Internal Server Error)
504伺服器沒有回應(Gateway Timeout)

Reference

Requests 函式庫 - Python 網路爬蟲教學 | STEAM 教育學習網

Python Requests post Method

response.status_code - Python requests - GeeksforGeeks

Python Requests - GeeksforGeeks

Python Requests Module

Requests: HTTP for Humans™ — Requests 2.32.5 documentation