Bạn luôn sử dụng Python để web scraping? Vậy bạn cũng phải bối rối về thư viện HTTP client tốt nhất giữa Urllib
, Urllib3
và Requests
như tôi đúng không?
Đúng vậy, trong lập trình Python, xử lý các yêu cầu HTTP là một yêu cầu phổ biến.
Python cung cấp nhiều thư viện để thực hiện chức năng này, và Urllib, Urllib3 và Requests là 3 thư viện phổ biến nhất.
Điều gì đặc biệt về chúng? Thư viện nào phù hợp với bạn?
Chúng đều có các tính năng và lợi ích độc đáo của riêng họ. Hãy bắt đầu đọc bài viết này và tìm hiểu nhé!
Thư viện | Urllib | Urllib3 | Requests |
---|---|---|---|
Yêu cầu cài đặt | Không | Có | Có |
Tốc độ | Trung bình | Nhanh | Trung bình |
Xử lý phản hồi | Thường cần các bước giải mã | Không cần bước giải mã thêm | Không cần bước giải mã thêm |
Connection pooling | Không hỗ trợ | Hỗ trợ | Hỗ trợ |
Dễ sử dụng | Cú pháp phức tạp hơn | Dễ sử dụng | Dễ sử dụng và thân thiện với người mới bắt đầu |
Urllib
là một phần của thư viện tiêu chuẩn của Python để xử lý URL, và bạn không cần phải cài đặt thêm bất kỳ thư viện nào để sử dụng nó.
Khi bạn sử dụng Urllib
để gửi yêu cầu, nó trả về một mảng byte của đối tượng phản hồi. Tuy nhiên, tôi phải nói rằng mảng byte được trả về của nó đòi hỏi một bước giải mã bổ sung, điều này có thể khó khăn đối với người mới bắt đầu.
Urllib
cho phép kiểm soát tinh vi với giao diện cấp thấp, nhưng điều này cũng có nghĩa là người dùng thường cần phải viết thêm mã. Vì vậy, người dùng thường cần phải tự động hóa mã hóa URL, thiết lập tiêu đề yêu cầu và giải mã phản hồi.
Nhưng đừng lo lắng! Urllib cung cấp các chức năng cơ bản của yêu cầu HTTP như yêu cầu GET và POST và nó cũng hỗ trợ phân tích cú pháp, mã hóa và giải mã URL.
Ưu điểm:
Nhược điểm:
Urllib
thích hợp cho các nhiệm vụ đơn giản như yêu cầu HTTP, đặc biệt là khi bạn không muốn cài đặt các thư viện bên thứ ba.
Nó cũng có thể học và hiểu các nguyên lý cơ bản. Vì vậy, người dùng có thể sử dụng nó để học và hiểu về cài đặt cơ bản của yêu cầu HTTP.
Tuy nhiên, do urllib
thiếu các tính năng nâng cao như quản lý connection pool, nén mặc định và xử lý JSON, việc sử dụng nó khá phức tạp, đặc biệt là đối với các yêu cầu HTTP phức tạp.
Urllib3
cung cấp các trừu tượng cấp cao, bao gồm API yêu cầu, connection pool, nén mặc định, mã hóa và giải mã JSON, và nhiều hơn nữa.
Áp dụng các tính năng này rất đơn giản! Bạn có thể tùy chỉnh yêu cầu HTTP chỉ với vài dòng mã. Urllib3
sử dụng các phần mở rộng C để cải thiện hiệu suất. Do đó, nó là nhanh nhất trong số ba thư viện.
Urllib3
cung cấp một giao diện cao cấp hơn. Nó cũng hỗ trợ các tính năng nâng cao như connection pool, tự động thử lại, cấu hình SSL và tải lên tập tin:
Ưu điểm:
Nhược điểm:
Người dùng có thể áp dụng urllib3
cho một số yêu cầu HTTP phức tạp, chẳng hạn như x
ử lý các yêu cầu song song, quản lý connection pool, v.v.
Urllib3 cũng phù hợp với một số yêu cầu cần hiệu suất và độ ổn định cao.
Requests
là một thư viện phổ biến để gửi các yêu cầu HTTP. Nó nổi tiếng với thiết kế API đơn giản và các chức năng mạnh mẽ, làm cho việc tương tác với mạng rất dễ dàng.
Các yêu cầu HTTP được gửi thông qua requests sẽ trở nên rất đơn giản và trực quan. Ngoài ra, nó có các chức năng tích hợp như xử lý cookie, phiên, cài đặt proxy và dữ liệu JSON, đảm bảo trải nghiệm thân thiện với người dùng.
Nó cũng có một số tính năng mạnh mẽ:
requests
nhờ vào các chức năng mã hóa và giải mã JSON tích hợp.Ưu điểm:
Requests
cung cấp giao diện đơn giản và dễ hiểu nhất. Do đó, việc gửi các yêu cầu HTTP sẽ rất dễ dàng.urllib3
tích hợp. Sử dụng urllib3
ở dưới cùng, kết hợp hiệu suất cao và các chức năng nâng cao trong khi che giấu sự phức tạp.Nhược điểm:
Requests
thích hợp cho hầu hết các kịch bản yêu cầu HTTP, đặc biệt là cho các web crawler và yêu cầu API. Nhờ vào cú pháp ngắn gọn và tài liệu phong phú, nó cũng đặc biệt thích hợp cho người mới bắt đầu.
Theo kết quả thử nghiệm, hiệu suất của ba thư viện này sau 100 lượt lặp là như sau:
Urllib
là thứ hai về tốc độ: thời gian yêu cầu trung bình là 1.18 giây. Mặc dù nó là một triển khai Python thuần túy, nhưng nó có hiệu suất tốt hơn nhờ vào cài đặt cơ bản.Urllib3
là nhanh nhất: thời gian yêu cầu trung bình là 0.33 giây. Điều này là do sự mở rộng C và quản lý connection pool hiệu quả.Requests
là chậm nhất: thời gian yêu cầu trung bình là 1.73 giây. Nhưng cú pháp ngắn gọn và tính năng phong phú của nó bù đắp cho điểm yếu này.Nhiều trang web đã tích hợp hệ thống chống bot để phát hiện và chặn các kịch bản tự động như web scraper. Vì vậy, việc bypass những rào cản này để truy cập dữ liệu là rất quan trọng!
Một cách để tránh bị phát hiện là sử dụng Nstbrowser để tránh chặn IP. Urllib và urllib3 cũng có khả năng tích hợp để thêm proxy vào các yêu cầu HTTP.
Nstbrowser được thiết kế với tính năng xoay IP và mở khóa web.
Thử Nstbrowser miễn phí để tránh chặn IP!
Bạn có suy nghĩ hoặc câu hỏi nào về việc thu thập dữ liệu web và Browseless không?
Hãy đến xem những gì các nhà phát triển khác đang chia sẻ trên Discord và Telegram!
Trước khi bắt đầu, bạn cần đáp ứng một số điều kiện sau:
Dưới đây là các bước cụ thể. Chúng ta sẽ lấy ví dụ về việc scrap nội dung tiêu đề của một trang trên website Amazon.
Nếu chúng ta cần scrap nội dung tiêu đề h3 của trang web sau:
Chúng ta sẽ chạy đoạn mã sau đây:
import json
from urllib.parse import urlencode
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as playwright:
config = {
"once": True,
"headless": True, # thiết lập chế độ headless
"autoClose": True,
"args": {"--disable-gpu": "", "--no-sandbox": ""}, # các đối số của trình duyệt nên là một từ điển
"fingerprint": {
"name": 'amazon_scraper',
"platform": 'mac', # hỗ trợ: windows, mac, linux
"kernel": 'chromium', # chỉ hỗ trợ: chromium
"kernelMilestone": '120',
"hardwareConcurrency": 8,
"deviceMemory": 8,
},
}
query = {'config': json.dumps(config)}
profileUrl = f"ws://127.0.0.1:8848/ws/connect?{urlencode(query)}"
print("URL Hồ sơ: ", profileUrl)
browser = await playwright.chromium.connect_over_cdp(endpoint_url=profileUrl)
try:
page = await browser.new_page()
await page.goto("https://www.amazon.com/b/?_encoding=UTF8&node=121225791011&pd_rd_w=Uoi8X&content-id=amzn1.sym.dde8a7c4-f315-46af-87af-ab98d7f18222&pf_rd_p=dde8a7c4-f315-46af-87af-ab98d7f18222&pf_rd_r=CM6698M8C3J02BBVTVM3&pd_rd_wg=olMbe&pd_rd_r=ff5d2eaf-26db-4aa4-a4dd-e74ea389f355&ref_=pd_hp_d_atf_unk&discounts-widget=%2522%257B%255C%2522state%255C%2522%253A%257B%255C%2522refinementFilters%255C%2522%253A%257B%257D%257D%252C%255C%2522version%255C%2522%253A1%257D%2522")
await page.wait_for_selector('h3')
title = await page.inner_text('h3')
print(title)
finally:
await browser.close()
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Trong mã trên, chúng ta chủ yếu đã thực hiện các bước sau:
Sau khi thực thi mã trên, cuối cùng bạn sẽ thấy kết quả đầu ra như sau:
Bước 1. Chúng ta nên sử dụng Playwright và Nstbrowser để truy cập vào một trang web có thể lấy thông tin tiêu đề yêu cầu hiện tại.
import json
from urllib.parse import urlencode
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as playwright:
config = {
"once": True,
"headless": True, # thiết lập chế độ headless
"autoClose": True,
"args": {"--disable-gpu": "", "--no-sandbox": ""}, # các đối số của trình duyệt nên là một từ điển
"fingerprint": {
"name": 'amazon_scraper',
"platform": 'mac', # hỗ trợ: windows, mac, linux
"kernel": 'chromium', # chỉ hỗ trợ: chromium
"kernelMilestone": '120',
"hardwareConcurrency": 8,
"deviceMemory": 8,
},
}
query = {'config': json.dumps(config)}
profileUrl = f"ws://127.0.0.1:8848/ws/connect?{urlencode(query)}"
print("URL Hồ sơ: ", profileUrl)
browser = await playwright.chromium.connect_over_cdp(endpoint_url=profileUrl)
try:
page = await browser.new_page()
await page.goto("https://httpbin.org/headers")
await page.wait_for_selector('pre')
content = await page.inner_text('pre')
print(content)
finally:
await browser.close()
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Thông qua mã trên, chúng ta sẽ thấy kết quả đầu ra như sau:
Bước 2. Chúng ta cần sử dụng Playwright để thêm thông tin tiêu đề yêu cầu bổ sung bằng cách thiết lập chặn yêu cầu khi tạo trang:
{
'sec-ch-ua': '\'Not A(Brand\';v=\'99\', \'Google Chrome\';v=\'121\', \'Chromium\';v=\'121\'',
'accept-Language': 'zh-CN,en;q=0.9'
}
import json
from urllib.parse import urlencode
from playwright.async_api import async_playwright
extra_headers = {
'sec-ch-ua': '\'Not A(Brand\';v=\'99\', \'Google Chrome\';v=\'121\', \'Chromium\';v=\'121\'',
'accept-Language': 'en-US,en;q=0.9'
}
async def main():
async with async_playwright() as playwright:
config = {
"once": True,
"headless": True, # thiết lập chế độ headless
"autoClose": True,
"args": ["--disable-gpu", "--no-sandbox"], # các đối số của trình duyệt nên là một danh sách
"fingerprint": {
"name": 'amazon_scraper',
"platform": 'mac', # hỗ trợ: windows, mac, linux
"kernel": 'chromium', # chỉ hỗ trợ: chromium
"kernelMilestone": '120',
"hardwareConcurrency": 8,
"deviceMemory": 8,
},
}
query = {'config': json.dumps(config)}
profileUrl = f"ws://127.0.0.1:8848/ws/connect?{urlencode(query)}"
print("URL Hồ sơ: ", profileUrl)
browser = await playwright.chromium.connect_over_cdp(endpoint_url=profileUrl)
try:
context = await browser.new_context()
page = await context.new_page()
# Thêm chặn yêu cầu để thiết lập các tiêu đề bổ sung
await page.route('**/*', lambda route, request: route.continue_(headers={**request.headers, **extra_headers}))
response = await page.goto("https://httpbin.org/headers")
print(await response.text())
finally:
await browser.close()
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Thông qua đoạn mã trên, chúng ta sẽ nhận được thông tin kết quả như sau, trong đó thông tin tiêu đề tùy chỉnh mà chúng ta thiết lập sẽ được thêm vào:
sec-ch-ua
.accept-Language
.Nói chung:
Requests
đã trở thành sự lựa chọn hàng đầu đối với hầu hết các nhà phát triển nhờ vào tính dễ sử dụng và các chức năng phong phú.Urllib3
xuất sắc khi hiệu suất và các tính năng nâng cao được yêu cầu.urllib
phù hợp với các dự án có yêu cầu phụ thuộc cao.Tùy thuộc vào nhu cầu và tình huống cụ thể của bạn, việc chọn công cụ phù hợp nhất sẽ giúp bạn xử lý các yêu cầu HTTP một cách hiệu quả hơn.