5.1 Giới thiệu về HttpClient
Trong Python, cũng như nhiều ngôn ngữ lập trình khác, có một
HttpClient tiêu chuẩn. Trong Python, nó được gọi là http.client
và cho phép
thực hiện các yêu cầu HTTP cấp thấp và làm việc với các phản hồi HTTP. Nó
cho phép tạo kết nối với các máy chủ HTTP và tương tác
với chúng.
Một module cấp thấp như http.client
cung cấp sự kiểm soát chi tiết hơn về các thao tác HTTP,
nhưng yêu cầu nhiều mã hơn để thực hiện các nhiệm vụ. Ngược lại, các module cấp cao như requests
,
cung cấp giao diện đơn giản hơn, che giấu nhiều chi tiết thực hiện.
Khả năng chính của http.client
Module http.client
cung cấp các khả năng chính sau:
- Tạo kết nối HTTP.
- Gửi yêu cầu HTTP.
- Đọc phản hồi HTTP.
- Xử lý tiêu đề và nội dung của các yêu cầu và phản hồi.
Khác với module requests
, module http.client
là
cấp thấp hơn và tập trung nhiều vào các chi tiết hoạt động
của yêu cầu http.
Các lớp và phương thức chính của http.client
Lớp/Phương thức | Mô tả |
---|---|
HTTPConnection |
Tạo kết nối HTTP. |
HTTPSConnection |
Tạo kết nối HTTPS. |
request(method, url, ...) |
Gửi yêu cầu HTTP. |
getresponse() |
Nhận phản hồi cho yêu cầu. |
response.status |
Mã trạng thái phản hồi. |
response.reason |
Mô tả văn bản của trạng thái phản hồi. |
response.read() |
Đọc dữ liệu phản hồi. |
response.getheaders() |
Nhận tất cả các tiêu đề phản hồi. |
response.getheader(name) |
Nhận giá trị của một tiêu đề cụ thể. |
Dưới đây chúng ta sẽ xem xét một số trong chúng chi tiết hơn.
5.2 Thực hiện GET-request
Để thực hiện yêu cầu sử dụng thư viện http.client
,
cần thực hiện theo thứ tự sau:
Thiết lập kết nối
Gửi yêu cầu
Nhận phản hồi
Đóng kết nối
Điều quan trọng cần lưu ý là đóng kết nối sau khi sử dụng là cần thiết để giải phóng tài nguyên và ngăn ngừa rò rỉ bộ nhớ. Điều này đặc biệt quan trọng khi làm việc với số lượng lớn các yêu cầu hoặc trong các ứng dụng chạy lâu dài.
Ví dụ sử dụng HTTPConnection
cho một yêu cầu HTTP thông thường:
import http.client
# Tạo kết nối HTTP
conn = http.client.HTTPConnection("example.com")
# Gửi yêu cầu GET
conn.request("GET", "/")
# Nhận phản hồi
response = conn.getresponse()
print(response.status, response.reason)
# Đóng kết nối
conn.close()
Ví dụ sử dụng HTTPSConnection
:
import http.client
# Tạo kết nối
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
# Gửi yêu cầu GET
conn.request("GET", "/posts/1")
# Nhận phản hồi
response = conn.getresponse()
print(response.status, response.reason)
# Đọc và giải mã dữ liệu phản hồi
data = response.read().decode('utf-8')
print(data)
# Nhận tất cả các tiêu đề phản hồi
headers = response.getheaders()
for header in headers:
print(f"{header[0]}: {header[1]}")
# Đóng kết nối
conn.close()
Dài hơn một chút so với khi sử dụng requests
, đúng không?
5.3 Thực hiện POST-request
POST-request
sử dụng http.client
được thực hiện rất giống với
GET-request
, chỉ có điều dữ liệu cần phải được đóng gói thành json-string
tự tay, và cũng cần chỉ định loại dữ liệu truyền
— thêm tiêu đề Content-Type
.
Ví dụ:
import http.client
import json
# Gửi yêu cầu POST
conn.request("POST", "/posts", body=payload, headers=headers)
Dưới body
cần truyền một json-object
đã được chuỗi hóa,
và dưới headers
— một từ điển chứa thông tin về loại dữ liệu.
Chúng có thể trông như thế này:
# Dữ liệu để gửi
payload = json.dumps({
"title": "foo",
"body": "bar",
"userId": 1
})
# Tiêu đề – loại nội dung truyền
headers = {
'Content-Type': 'application/json'
}
Khi đó mã đầy đủ của POST-request
sẽ như sau:
import http.client
import json
# Dữ liệu để gửi
payload = json.dumps({
"title": "foo",
"body": "bar",
"userId": 1
})
# Tiêu đề
headers = {
'Content-Type': 'application/json'
}
# Tạo kết nối
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
# Gửi yêu cầu POST
conn.request("POST", "/posts", body=payload, headers=headers)
# Nhận phản hồi
response = conn.getresponse()
print(response.status, response.reason)
# Đọc và giải mã dữ liệu phản hồi
data = response.read().decode('utf-8')
print(data)
# Đóng kết nối
conn.close()
5.4 Xử lý lỗi khi thực hiện yêu cầu
Mình nghĩ sẽ hữu ích nếu đưa ra một ví dụ về xử lý lỗi, vì nó
khác biệt so với hành vi của requests
. Trong module http.client
, ngoại lệ
được ném ra tự động
, nếu có
vấn đề với kết nối hoặc các lỗi HTTP khác.
Ví dụ:
import http.client
try:
# Tạo kết nối
conn = http.client.HTTPSConnection("jsonplaceholder.typicode.com")
# Gửi yêu cầu GET
conn.request("GET", "/posts/1")
# Nhận phản hồi
response = conn.getresponse()
print(response.status, response.reason)
# Đọc và giải mã dữ liệu phản hồi
data = response.read().decode('utf-8')
print(data)
except http.client.HTTPException as e:
print("Đã xảy ra lỗi HTTP:", e)
except Exception as e:
print("Đã xảy ra lỗi:", e)
finally:
# Đóng kết nối
conn.close()
Nói gì nhỉ? Sử dụng module requests tất nhiên là dễ hơn. Nhưng! Nhiều module và framework sử dụng dưới nắp thấp hơn http.client. Bạn cần biết cách làm việc với nó, để bạn có thể cấu hình đúng công việc của chúng.
GO TO FULL VERSION