Lớp ThreadPoolExecutor trong Python có thể được sử dụng để kiểm tra trạng thái của nhiều trang web đồng thời
Sử dụng các chuỗi để kiểm tra trạng thái trang web có thể tăng tốc đáng kể quá trình so với việc kiểm tra trạng thái của từng trang web một cách tuần tự, từng cái một
Trong hướng dẫn này, bạn sẽ khám phá cách kiểm tra đồng thời trạng thái của các trang web trên internet bằng nhóm luồng trong Python
Sau khi hoàn thành hướng dẫn này, bạn sẽ biết
- Cách kiểm tra tuần tự trạng thái của các trang web trên internet bằng Python và mức độ chậm của nó
- Cách sử dụng ThreadPoolExecutor để quản lý nhóm luồng công nhân.
- Cách cập nhật mã để kiểm tra nhiều trang web cùng lúc và tăng tốc đáng kể quá trình
Hãy đi sâu vào
Mục lục
- Kiểm tra từng trang một [từ từ]
- Tạo một nhóm chủ đề công nhân với ThreadPoolExecutor
- Bước 1. Tạo nhóm chủ đề
- Bước 2. Gửi nhiệm vụ đến Thread Pool
- Bước 3. Nhận kết quả khi hoàn thành nhiệm vụ
- Bước 4. Tắt nhóm chủ đề
- Kiểm tra trạng thái của các trang web đồng thời
- Đọc thêm
- mang đi
Kiểm tra từng trang một [từ từ]
Kiểm tra trạng thái của các trang web trên internet là một nhiệm vụ phổ biến
Ví dụ
- Bạn có thể cần kiểm tra xem một bộ trang web của công ty có thể truy cập được hay không và thực hiện hành động nếu chúng không truy cập được
- Bạn có thể cần kiểm tra xem các trang web có bắt đầu phát sinh lỗi hay không, chẳng hạn như khi tải nặng
- Bạn có thể cần kiểm tra xem kết nối internet của mình có hoạt động bình thường không
Có những dịch vụ chuyên nghiệp mà chúng tôi có thể sử dụng cho một số nhiệm vụ này. Tuy nhiên, đôi khi chúng tôi cần một tập lệnh nhanh để kiểm tra trạng thái của một số trang web
Có nhiều cách để kiểm tra trạng thái của một trang web bằng Python thông qua HTTP
Có lẽ cách phổ biến nhất là mở kết nối đến máy chủ bằng cách sử dụng urlopen[]< . function, then call the getcode[] function on the open HTTPSConnection.
Bạn có thể tìm hiểu thêm về các hàm thư viện chuẩn này tại đây
- urllib. yêu cầu – Thư viện mở rộng để mở URL
- http. máy khách — máy khách giao thức HTTP
Ví dụ: chúng ta có thể sử dụng trình quản lý bối cảnh để mở kết nối HTTP và lấy mã trạng thái, mã này sẽ đảm bảo rằng kết nối sẽ tự động đóng khi chúng ta thoát khỏi khối một cách bình thường hoặc nếu một ngoại lệ được đưa ra
1
2
3
4
5
6
.. .
# mở kết nối đến máy chủ
với urlopen[url] as connection:
# lấy mã phản hồi, e. g. 200
mã = kết nối. lấy mã[]
#.
Ngoài ra, do chúng tôi có thể gọi tập lệnh này nhiều lần trong điều kiện kết nối internet có thể bị gián đoạn, chúng tôi cũng có thể muốn thêm thời gian chờ cho nỗ lực kết nối, có thể là vài giây
Điều này có thể đạt được khi gọi urlopen[] function via the timeout argument.
1
2
3
4
5
.. .
# mở kết nối đến máy chủ khi hết thời gian chờ
với urlopen[url, timeout=3] as connection:
# lấy mã phản hồi, e. g. 200
mã = kết nối. lấy mã[]
Việc mở kết nối HTTP có thể không thành công vì nhiều lý do, chẳng hạn như các URL dẫn đến máy chủ không đúng định dạng
Chúng tôi có thể chọn xử lý một số trường hợp này và trả về một thông báo thích hợp
Ví dụ: nếu chúng tôi có thể kết nối nhưng máy chủ báo lỗi, thì Lỗi HTTP sẽ xuất hiện để chúng tôi có thể truy xuất .
1
2
3
4
5
6
7
8
9
10
.. .
#xử lý lỗi kết nối
thử.
# mở kết nối đến máy chủ khi hết thời gian chờ
với urlopen[url, timeout=3] as connection:
# nhận mã phản hồi, e. g. 200
mã = kết nối. lấy mã[]
#.
ngoại trừ Lỗi HTTP as e.
return e. mã
Hoặc, Lỗi URL có thể xuất hiện nếu chúng tôi không thể kết nối, có thể do miền không thể được phân giải qua DNS, trong đó .
1
2
3
4
5
6
7
8
9
10
11
12
.. .
#xử lý lỗi kết nối
thử.
# mở kết nối đến máy chủ khi hết thời gian chờ
với urlopen[url, timeout=3] as connection:
# nhận mã phản hồi, e. g. 200
mã = kết nối. lấy mã[]
#.
ngoại trừ Lỗi HTTP as e.
return e. mã
ngoại trừ Lỗi URL as e.
return e. lý do
Cuối cùng, nếu điều gì đó khác xảy ra và điều này luôn có thể xảy ra, thì chúng tôi có thể truy xuất các bẫy và trả về các lỗi chung hơn
Bạn có thể tìm hiểu thêm về các lỗi này tại đây
- urllib. lỗi - Các lớp ngoại lệ được đưa ra bởi urllib. yêu cầu
Liên kết cái này lại với nhau, hàm get_website_status[] .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# lấy trạng thái của một trang web
def get_website_status[url]:
# xử lý lỗi kết nối
thử.
# mở kết nối đến máy chủ khi hết thời gian chờ
với urlopen[url, timeout=3] as connection:
# lấy mã phản hồi, e. g. 200
mã = kết nối. lấy mã[]
trả lại mã
ngoại trừ Lỗi HTTP as e:
trả lại e. mã
ngoại trừ Lỗi URL as e:
trả lại e. lý do
ngoại trừ.
trả lại e
Khi chúng tôi có trạng thái lỗi, chúng tôi cần diễn giải nó
Python cung cấp mô-đun http và lớp HTTPStatus .
Tuy nhiên, chúng tôi có thể giữ cho tập lệnh của mình đơn giản bằng cách kiểm tra trạng thái 200 [OK], nếu không thì báo lỗi
Hàm get_status[] bên dưới nhận HTTP . get_website_status[] function and interprets it with a human readable message as 'OK' or 'ERROR'.
1
2
3
4
5
# diễn giải mã phản hồi HTTP thành trạng thái
def get_status[mã]:
nếu mã == HTTPStatus.Được.
trả lại 'OK'
return 'ERROR'
Tiếp theo, chúng tôi cần lấy trạng thái, diễn giải trạng thái đó và báo cáo kết quả cho từng URL trong danh sách URL
Điều này liên kết chương trình lại với nhau
Danh sách URL có thể được tải từ cơ sở dữ liệu hoặc tệp văn bản trong thực tế. Trong trường hợp này, chúng tôi sẽ xác định một hằng số có tên URLS liệt kê mười trang web phổ biến nhất trên internet không theo thứ tự cụ thể.
1
2
3
4
5
6
7
8
9
10
11
# danh sách các url để kiểm tra
URL = ['https. //twitter. com',
'https. //Google. com',
'https. //Facebook. com',
'https. // reddit. com',
'https. //youtube. com',
'https. // amazon. com',
'https. //wikipedia. tổ chức',
'https. //ebay. com',
'https. // mạng xã hội. com',
'https. // cnn. com']
Sau đó, chúng ta có thể xác định một hàm nhận danh sách các URL và nhận trạng thái của từng URL bằng cách gọi trước get_website_status[< . ] function to get the HTTP code, then to get_status[] to interpret the code, before calling the print function to report the status.
1
2
3
4
5
6
7
.. .
# lấy trạng thái cho trang web
mã = get_website_status[url]
# diễn giải trạng thái
status = get_status[mã]
# báo cáo tình trạng
in[f'{url. 20s}\t{trạng thái. 5s}\t{code}']
Liên kết cái này lại với nhau, cái tên check_status_urls[] .
1
2
3
4
5
6
7
8
9
# kiểm tra trạng thái của danh sách các trang web
def check_status_urls[urls]:
cho url trong url:
# lấy trạng thái cho trang web
mã = get_website_status[url]
# diễn giải trạng thái
trạng thái = get_status[code]
# trạng thái báo cáo
in[f'{url. 20s}\t{trạng thái. 5s}\t{code}']
Sau đó, chúng tôi có thể gọi chức năng này mà không cần danh sách URL được xác định trước
1
2
3
.. .
# kiểm tra tất cả các url
check_status_urls[URL]
Và đó là nó
Liên kết điều này lại với nhau, ví dụ hoàn chỉnh về kiểm tra trạng thái của danh sách URL được liệt kê bên dưới
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#Trăn Siêu Nhanh. com
# ví dụ về ping trạng thái của một nhóm trang web
từ urllib. yêu cầu nhập urlopen
từ urllib. lỗi nhập Lỗi URL
từ urllib. lỗi nhập Lỗi HTTP
từ http nhập HTTPStatus
# lấy trạng thái của một trang web
def get_website_status[url]:
# xử lý lỗi kết nối
thử.
# mở kết nối đến máy chủ khi hết thời gian chờ
với urlopen[url, timeout=3] as connection:
# lấy mã phản hồi, e. g. 200
mã = kết nối. lấy mã[]
trả lại mã
ngoại trừ Lỗi HTTP as e:
trả lại e. mã
ngoại trừ Lỗi URL as e:
trả lại e. lý do
ngoại trừ.
trả lại e
# diễn giải mã phản hồi HTTP thành trạng thái
def get_status[mã]:
nếu mã == HTTPStatus.Được.
trả lại 'OK'
return 'ERROR'
# kiểm tra trạng thái của danh sách các trang web
def check_status_urls[urls]:
cho url trong url:
# lấy trạng thái cho trang web
mã = get_website_status[url]
# diễn giải trạng thái
trạng thái = get_status[code]
# trạng thái báo cáo
in[f'{url. 20s}\t{trạng thái. 5s}\t{code}']
# danh sách các url để kiểm tra
URL = ['https. //twitter. com',
'https. //Google. com',
'https. //Facebook. com',
'https. // reddit. com',
'https. //youtube. com',
'https. // amazon. com',
'https. //wikipedia. tổ chức',
'https. //ebay. com',
'https. // mạng xã hội. com',
'https. // cnn. com']
# kiểm tra tất cả các url
check_status_urls[URL]
Chạy ví dụ này sẽ nhận được mã trạng thái, mã này sau đó được diễn giải và báo cáo cho từng URL trong danh sách
Trong trường hợp này, tất cả các URL báo cáo trạng thái OK ngoại trừ amazon. com báo lỗi 503. Có thể là do amazon thích tiền tố www hoặc vì nó không thích bị ping bởi các ứng dụng web không xác định.
1
2
3
4
5
6
7
8
9
10
https. //twitter. com OK 200
https. //Google. com OK 200
https. //Facebook. com OK 200
https. // reddit. com OK 200
https. //youtube. com OK 200
https. // amazon. com LỖI 503
https. //wikipedia. tổ chức OK 200
https. //ebay. com OK 200
https. // mạng xã hội. com OK 200
https. // cnn. com OK 200
Kiểm tra từng trạng thái của trang web bị chậm
Trên hệ thống của tôi, chỉ mất chưa đầy mười giây để truy vấn tất cả mười trang web
Mất bao lâu để chạy trên hệ thống của bạn?
Hãy cho tôi biết trong phần nhận xét bên dưới.
Tiếp theo, chúng ta sẽ xem xét
ThreadPoolExecutorlớp có thể được sử dụng để tạo một nhóm các luồng công nhân sẽ cho phép chúng tôi tăng tốc quá trình kiểm tra trạng tháiChạy các vòng lặp của bạn bằng cách sử dụng tất cả các CPU, tải xuống cuốn sách MIỄN PHÍ của tôi để tìm hiểu cách thực hiện
Tạo một nhóm chủ đề công nhân với ThreadPoolExecutor
Chúng tôi có thể sử dụng ThreadPoolExecutor để tăng tốc độ tải xuống nhiều tệp được liệt kê trên trang web HTML.
Các
ThreadPoolExecutorlớp được cung cấp như một phần của đồng thời. mô-đun tương lai để dễ dàng chạy các tác vụ đồng thờiCác
ThreadPoolExecutor cung cấp một nhóm các luồng công nhân, khác với ProcessPoolExecutorcung cấp một nhóm các quy trình công nhânNói chung là,
ThreadPoolExecutor nên được sử dụng cho các tác vụ liên kết IO đồng thời, như tải xuống URL và ProcessPoolExecutornên được sử dụng cho các tác vụ liên quan đến CPU đồng thời, như tính toánSử dụng
ThreadPoolExecutorđược thiết kế để dễ dàng và đơn giản. Nó giống như “chế độ tự động” cho Python thread- Tạo nhóm luồng bằng cách gọi ThreadPoolExecutor[] .
- Gửi nhiệm vụ và nhận tương lai bằng cách gọi submit[].
- Chờ và nhận kết quả khi nhiệm vụ hoàn thành bằng cách gọi as_completed[].
- Tắt nhóm luồng bằng cách gọi shutdown[]
Bước 1. Tạo nhóm chủ đề
Đầu tiên, một
ThreadPoolExecutorví dụ phải được tạo raTheo mặc định, nó sẽ tạo một nhóm bằng số lượng CPU hợp lý bạn có sẵn cộng với bốn
Điều này là tốt cho hầu hết các mục đích
1
2
3
.. .
# tạo nhóm luồng với số lượng luồng công nhân mặc định
người thi hành = Người thi hành ThreadPool[]
Bạn có thể chạy hàng chục đến hàng trăm luồng liên kết IO đồng thời trên mỗi CPU, mặc dù có thể không phải hàng nghìn hoặc hàng chục nghìn
Bạn có thể chỉ định số lượng chuỗi sẽ tạo trong nhóm thông qua đối số max_workers ; .
1
2
3
.. .
# tạo nhóm luồng với 10 luồng công nhân
executor = ThreadPoolExecutor[max_workers=10]
Bước 2. Gửi nhiệm vụ đến Thread Pool
Sau khi được tạo, nó có thể gửi các tác vụ vào nhóm để hoàn thành bằng cách sử dụng gửi[] . function.
Hàm này lấy tên của hàm để gọi bất kỳ và tất cả các đối số và trả về một
Tương laivậtĐối tượng Tương lai là lời hứa trả về kết quả từ tác vụ [nếu có] và cung cấp cách xác định xem một tác vụ cụ thể có .
1
2
3
.. .
# gửi một nhiệm vụ và nhận một tương lai
tương lai = người thi hành. gửi[nhiệm vụ, arg1 . , arg2, .. . ]
Có thể truy cập kết quả trả về từ một hàm do nhóm luồng thực thi thông qua kết quả[] function on the
Tương laivật. Nó sẽ đợi cho đến khi có kết quả nếu cần hoặc trả về ngay nếu có kết quảVí dụ
1
2
3
.. .
# lấy kết quả từ một tương lai
kết quả = tương lai. kết quả[]
Một cách tiếp cận thay thế và có lẽ đơn giản hơn để gửi các tác vụ không đồng bộ đến nhóm luồng là sử dụng bản đồ[] function provided on the ThreadPoolExecutor.
Nó hoạt động giống như tích hợp sẵn
map[]chức năng. Nó lấy tên của hàm tác vụ đích và một hàm có thể lặp lại. Hàm mục tiêu sau đó được gọi cho từng mục trong lần lặp và vì chúng tôi đang sử dụng nhóm luồng nên mỗi lệnh gọi được gửi dưới dạng tác vụ không đồng bộCác
map[] sau đó trả về một lần lặp trên kết quả từ mỗi lệnh gọi hàm. Chúng ta có thể gọi hàm map[]chức năng và lặp trực tiếp các kết quả trong một vòng lặp for;1
2
3
# thực hiện tất cả các nhiệm vụ song song
cho kết quả trong người thi hành. bản đồ[nhiệm vụ, mục . ]:
#
Bước 3. Nhận kết quả khi hoàn thành nhiệm vụ
Cái hay của việc thực hiện các nhiệm vụ đồng thời là chúng ta có thể nhận được kết quả khi chúng có sẵn, thay vì đợi các nhiệm vụ được hoàn thành theo thứ tự chúng đã được gửi
The đồng thời. Mô-đun tương lai cung cấp một as_completed[] function that we can use to get results for tasks as they are completed, just like its name suggests.
Chúng ta có thể gọi hàm và cung cấp cho nó danh sách các đối tượng trong tương lai được tạo bằng cách gọi submit[ . and it will return future objects as they are completed in whatever order.
Ví dụ: chúng ta có thể sử dụng cách hiểu danh sách để gửi nhiệm vụ và tạo danh sách
Tương laicác đối tượng1
2
3
.. .
# gửi tất cả các tác vụ vào nhóm luồng và tạo danh sách tương lai
tương lai = [nhóm. gửi[công việc, nhiệm vụ] for task in tasks]
Sau đó nhận kết quả cho các tác vụ khi chúng hoàn thành trong vòng lặp for
1
2
3
4
5
# lặp lại tất cả các nhiệm vụ đã gửi và nhận kết quả khi chúng có sẵn
cho tương lai trong as_completed[futures]:
# lấy kết quả
kết quả = tương lai. kết quả[]
# làm điều gì đó với kết quả
Bước 4. Tắt nhóm chủ đề
Khi tất cả các tác vụ được hoàn thành, chúng tôi có thể đóng nhóm luồng, thao tác này sẽ giải phóng từng luồng và mọi tài nguyên mà nó có thể giữ [e. g. không gian ngăn xếp]
1
2
3
.. .
# tắt nhóm chủ đề
người thi hành. tắt máy[]
Một cách dễ dàng hơn để sử dụng nhóm luồng là thông qua trình quản lý ngữ cảnh [từ khóa với ], đảm bảo nhóm luồng sẽ tự động đóng sau khi chúng tôi .
1
2
3
4
5
6
7
8
9
10
.. .
# tạo nhóm chủ đề
với ThreadPoolExecutor[max_workers=10] as executor:
# gửi nhiệm vụ
tương lai = [người thi hành. gửi[công việc, nhiệm vụ] for task in tasks]
# nhận kết quả khi chúng có sẵn
cho tương lai trong as_completed[futures]:
# lấy kết quả
kết quả = tương lai. kết quả[]
# làm điều gì đó với kết quả
Bây giờ chúng ta đã quen thuộc với ThreadPoolExecutor và cách sử dụng nó, hãy xem cách chúng ta có thể điều chỉnh chương trình của mình để kiểm tra trạng thái của .
Bối rối với API lớp ThreadPoolExecutor?
Tải xuống bảng cheat PDF MIỄN PHÍ của tôi
Kiểm tra trạng thái của các trang web đồng thời
Chúng tôi có thể cập nhật chương trình của mình để sử dụng
ThreadPoolExecutorvới rất ít thay đổiTất cả các thay đổi đều có trong check_status_urls[] function.
Đầu tiên, chúng ta có thể tạo nhóm luồng bằng trình quản lý ngữ cảnh và đặt số lượng luồng công nhân thành số lượng URL trong danh sách của chúng tôi. Bằng cách này, chúng tôi có thể cố gắng truy vấn tất cả mười trang web cùng một lúc
1
2
3
4
.. .
# tạo nhóm chủ đề
với ThreadPoolExecutor[len[urls]] as executor:
#
Tiếp theo, chúng ta cần thực hiện lệnh gọi không đồng bộ tới get_website_status[] function.
Có lẽ cách tiếp cận đơn giản nhất là sử dụng bản đồ[] function on the
ThreadPoolExecutor .Mỗi tác vụ là một lệnh gọi đến get_website_status[] with a URL argument that returns an HTTP response code that we can then interpret and report.
1
2
3
4
5
6
7
.. .
# kiểm tra trạng thái của từng url
cho mã trong trình thực thi. bản đồ[get_website_status, urls . ]:
# diễn giải trạng thái
status = get_status[code]
# trạng thái báo cáo
in[f'{status. 5s}\t{code}']
Vấn đề với phương pháp này là chúng tôi không có cách nào để liên kết mã phản hồi HTTP với từng URL
Chúng tôi có thể thêm bộ đếm và tăng nó khi chúng tôi lặp lại kết quả, sau đó sử dụng bộ đếm để truy cập địa chỉ thích hợp trong danh sách URL
Phiên bản tốt hơn của giải pháp này trước tiên là truy xuất kết quả có thể lặp lại từ cuộc gọi đến
bản đồ[] .1
2
3
.. .
# kiểm tra trạng thái của từng url
kết quả = người thi hành. bản đồ[get_website_status, urls]
Sau đó, chúng ta có thể gọi bảng liệt kê[] được xây dựng . Chỉ mục có thể được sử dụng trực tiếp để lấy URL trong danh sách cho kết quả.
1
2
3
4
5
6
.. .
# liệt kê các kết quả theo thứ tự như danh sách các url
cho i,mã trong enumerate[results]:
# lấy url
url = url[i]
#.
Ví dụ
1
2
3
4
5
6
7
8
9
10
11
.. .
# kiểm tra trạng thái của từng url
kết quả = người thi hành. bản đồ[get_website_status, urls]
# liệt kê các kết quả theo thứ tự như danh sách các url
cho i,mã trong enumerate[results]:
# lấy url
url = url[i]
# diễn giải trạng thái
status = get_status[code]
# trạng thái báo cáo
in[f'{url. 20s}\t{trạng thái. 5s}\t{code}']
Kết hợp điều này lại với nhau, ví dụ hoàn chỉnh về truy vấn danh sách trang web không đồng bộ bằng cách sử dụng ThreadPoolExecutor trong Python được liệt kê bên dưới.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#Trăn Siêu Nhanh. com
# ví dụ về việc ping trạng thái của một nhóm trang web không đồng bộ
từ urllib. yêu cầu nhập urlopen
từ urllib. lỗi nhập Lỗi URL
từ urllib. lỗi nhập Lỗi HTTP
từ http nhập HTTPStatus
từ đồng thời. tương lai nhập ThreadPoolExecutor
từ đồng thời. tương lai nhập as_ đã hoàn thành
# lấy trạng thái của một trang web
def get_website_status[url]:
# xử lý lỗi kết nối
thử.
# mở kết nối đến máy chủ khi hết thời gian chờ
với urlopen[url, timeout=3] as connection:
# lấy mã phản hồi, e. g. 200
mã = kết nối. lấy mã[]
trả lại mã
ngoại trừ Lỗi HTTP as e:
trả lại e. mã
ngoại trừ Lỗi URL as e:
trả lại e. lý do
ngoại trừ.
trả lại e
# diễn giải mã phản hồi HTTP thành trạng thái
def get_status[mã]:
nếu mã == HTTPStatus.Được.
trả lại 'OK'
return 'ERROR'
# kiểm tra trạng thái của danh sách các trang web
def check_status_urls[urls]:
# tạo nhóm chủ đề
với ThreadPoolExecutor[len[urls]] as executor:
# kiểm tra trạng thái của từng url
kết quả = người thi hành. bản đồ[get_website_status, urls]
# liệt kê kết quả theo thứ tự giống như danh sách url
cho i,mã in enumerate[results]:
# lấy url
url = url[i]
# diễn giải trạng thái
status = get_status[code]
# trạng thái báo cáo
in[f'{url. 20s}\t{trạng thái. 5s}\t{code}']
# danh sách các url để kiểm tra
URL = ['https. //twitter. com',
'https. //Google. com',
'https. //Facebook. com',
'https. // reddit. com',
'https. //youtube. com',
'https. // amazon. com',
'https. //wikipedia. tổ chức',
'https. //ebay. com',
'https. // mạng xã hội. com',
'https. // cnn. com']
# kiểm tra tất cả các url
check_status_urls[URL]
Chạy ví dụ báo cáo các trang web và trạng thái của chúng như trước, nhưng lần này, mã nhanh hơn nhiều
Trên hệ thống của tôi, tất cả các trang web được truy vấn trong khoảng 1. 5 giây, nhanh hơn nhiều so với gần mười giây trong phiên bản tuần tự, tăng tốc khoảng 5 lần
1
2
3
4
5
6
7
8
9
10
https. //twitter. com OK 200
https. //Google. com OK 200
https. //Facebook. com OK 200
https. // reddit. com OK 200
https. //youtube. com OK 200
https. // amazon. com OK 200
https. //wikipedia. tổ chức OK 200
https. //ebay. com OK 200
https. // mạng xã hội. com OK 200
https. // cnn. com OK 200
Điều gì sẽ xảy ra nếu chúng ta muốn sử dụng
submit[]chức năng gửi các tác vụ và báo cáo trạng thái cho các kết quả khi các tác vụ được hoàn thành, thay vì thứ tự các URL được liệt kê?Điều này sẽ yêu cầu một giải pháp phức tạp hơn một chút
Hãy nhớ rằng hàm submit[] trả về một . Ví dụ: chúng ta có thể sử dụng khả năng hiểu danh sách để tạo danh sách Future object that provides a handle on the asynchronous task. For example, we can use a list comprehension to create a list of
Các đối tượng đối tượng bằng cách gọi gửi[] cho hàm get_website_status[]chức năng với từng URL trong danh sách URL1
2
3
.. .
# gửi từng url dưới dạng tác vụ
tương lai = [người thi hành. gửi[get_website_status, url] for url in urls]
Phần khó khăn là chúng tôi không có cách nào để liên kết
Tương laihoặc kết quả của nó với URLChúng tôi có thể liệt kê các hợp đồng tương lai theo thứ tự giống như danh sách URL và sử dụng liệt kê[] function as we did with the iterable of results returned when calling map[]; for example:
1
2
3
4
5
6
7
8
9
10
11
12
13
.. .
# gửi từng url dưới dạng tác vụ
tương lai = [người thi hành. gửi[get_website_status, url] for url in urls]
# nhận kết quả khi chúng có sẵn
cho i,tương lai trong enumerate[futures]:
# lấy url cho tương lai
url = url[i]
# lấy trạng thái cho trang web
mã = tương lai. kết quả[]
# diễn giải trạng thái
status = get_status[code]
# trạng thái báo cáo
in[f'{url. 20s}\t{trạng thái. 5s}\t{code}']
Điều này sẽ hoạt động, nhưng nó là một phiên bản gọi phức tạp hơn
bản đồ[]; . bản đồ[] .Việc báo cáo trạng thái trang web khi có sẵn thông qua as_completed[] function.
Một cách tiếp cận khác là tạo một từ điển ánh xạ từng đối tượng Tương lai với dữ liệu được chuyển đến Future’s task, in this case, the URL argument to get_website_status[]. This idea is also suggested in the ThreadPoolExecutor .
Ví dụ
1
2
3
.. .
# gửi từng tác vụ, tạo ánh xạ tương lai tới các url
future_to_url = {người thi hành. gửi[get_website_status, url . ]:url cho url trong url}
Sau đó chúng ta có thể gọi
as_completed[] với từ điển future_to_urlfuture_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . future_to_url] . từ điển và xử lý các đối tượng Tương laiđồ vật theo thứ tự hoàn thành1
2
3
4
.. .
# nhận kết quả khi chúng có sẵn
cho tương lai trong as_completed[future_to_url]:
#
Sau đó, chúng tôi có thể tra cứu giá trị URL trong
future_to_url từ điển cho khóa Tương laiChìa khóa;1
2
3
.. .
# lấy url cho tương lai
url = future_to_url[tương lai]
Bây giờ chúng tôi có mọi thứ chúng tôi cần để báo cáo trạng thái trang web theo thứ tự trạng thái được trả về, thay vì thứ tự mà chúng tôi truy vấn các trang web. Điều này có thể nhanh hơn và phản hồi nhanh hơn một chút so với phiên bản tuyến tính
Phiên bản cập nhật của hàm check_status_urls[] .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# kiểm tra trạng thái của danh sách các trang web
def check_status_urls[urls]:
# tạo nhóm chủ đề
với ThreadPoolExecutor[len[urls]] as executor:
# gửi từng tác vụ, tạo ánh xạ tương lai tới các url
future_to_url = {người thi hành.gửi[get_website_status, url . ]:url cho url trong url}
# nhận kết quả khi có sẵn
cho tương lai trong as_completed[future_to_url]:
# lấy url cho tương lai
url = future_to_url[future]
# lấy trạng thái cho trang web
mã = tương lai. kết quả[]
# diễn giải trạng thái
status = get_status[code]
# trạng thái báo cáo
in[f'{url. 20s}\t{trạng thái. 5s}\t{code}']
Liên kết điều này lại với nhau, ví dụ đầy đủ về truy vấn các trang web và báo cáo kết quả theo thứ tự hoàn thành nhiệm vụ được liệt kê bên dưới
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#Trăn Siêu Nhanh. com
# ví dụ về việc ping trạng thái của một nhóm trang web không đồng bộ
từ urllib. yêu cầu nhập urlopen
từ urllib. lỗi nhập Lỗi URL
từ urllib. lỗi nhập Lỗi HTTP
từ http nhập HTTPStatus
từ đồng thời. tương lai nhập ThreadPoolExecutor
từ đồng thời. tương lai nhập as_ đã hoàn thành
# lấy trạng thái của một trang web
def get_website_status[url]:
# xử lý lỗi kết nối
thử.
# mở kết nối đến máy chủ khi hết thời gian chờ
với urlopen[url, timeout=3] as connection:
# lấy mã phản hồi, e. g. 200
mã = kết nối. lấy mã[]
trả lại mã
ngoại trừ Lỗi HTTP as e:
trả lại e. mã
ngoại trừ Lỗi URL as e:
trả lại e. lý do
ngoại trừ.
trả lại e
# diễn giải mã phản hồi HTTP thành trạng thái
def get_status[mã]:
nếu mã == HTTPStatus.Được.
trả lại 'OK'
return 'ERROR'
# kiểm tra trạng thái của danh sách các trang web
def check_status_urls[urls]:
# tạo nhóm chủ đề
với ThreadPoolExecutor[len[urls]] as executor:
# gửi từng tác vụ, tạo ánh xạ tương lai tới các url
future_to_url = {người thi hành.gửi[get_website_status, url . ]:url cho url trong url}
# nhận kết quả khi có sẵn
cho tương lai trong as_completed[future_to_url]:
# lấy url cho tương lai
url = future_to_url[future]
# lấy trạng thái cho trang web
mã = tương lai. kết quả[]
# diễn giải trạng thái
status = get_status[code]
# trạng thái báo cáo
in[f'{url. 20s}\t{trạng thái. 5s}\t{code}']
# danh sách các url để kiểm tra
URL = ['https. //twitter. com',
'https. //Google. com',
'https. //Facebook. com',
'https. // reddit. com',
'https. //youtube. com',
'https. // amazon. com',
'https. //wikipedia. tổ chức',
'https. //ebay. com',
'https. // mạng xã hội. com',
'https. // cnn. com']
# kiểm tra tất cả các url
check_status_urls[URL]
Chạy ví dụ này, chúng ta có thể thấy rằng trạng thái trang web được báo cáo theo thứ tự khác với danh sách URL
Cụ thể, kết quả được báo cáo theo thứ tự các trang web trả lời truy vấn. Chúng ta có thể thấy rằng Amazon phản hồi chậm nhất, có thể là do nó không thích địa chỉ cụ thể hoặc ứng dụng khách Python mà chúng ta đang sử dụng để thực hiện truy vấn
Trên hệ thống của tôi, ví dụ này cũng nhanh hơn một chút, chỉ mất một phần giây
1
2
3
4
5
6
7
8
9
10
https. //twitter. com OK 200
https. // cnn. com OK 200
https. // reddit. com OK 200
https. //youtube. com OK 200
https. //Google. com OK 200
https. //wikipedia. tổ chức OK 200
https. //Facebook. com OK 200
https. // mạng xã hội. com OK 200
https. //ebay. com OK 200
https. // amazon. com LỖI 503
Khóa học Python ThreadPoolExecutor miễn phí
Tải xuống bảng gian lận API ThreadPoolExecutor của tôi và như một phần thưởng, bạn sẽ có quyền truy cập MIỄN PHÍ vào khóa học email 7 ngày của tôi
Khám phá cách sử dụng lớp ThreadPoolExecutor bao gồm cách định cấu hình số lượng công nhân và cách thực thi tác vụ không đồng bộ
Tìm hiểu thêm
Đọc thêm
Phần này cung cấp các tài nguyên bổ sung mà bạn có thể thấy hữu ích
Sách
- ThreadPoolExecutor Jump-Start, Jason Brownlee, 2022 [cuốn sách của tôi. ]
- Câu hỏi phỏng vấn về API hợp đồng tương lai đồng thời
- Bảng gian lận API lớp ThreadPoolExecutor
Tôi cũng giới thiệu các chương cụ thể từ những cuốn sách sau
- Python hiệu quả, Brett Slatkin, 2019
- Xem Chương 7. Đồng thời và song song
- Sơ lược về Python, Alex Martelli, et al. , 2017
- Nhìn thấy. chương. 14. Chủ đề và quy trình
hướng dẫn
- ThreadPoolExecutor. Hướng dẫn hoàn chỉnh
API
- đồng thời. tương lai - Khởi chạy các tác vụ song song
Choáng ngợp trước các API đồng thời của python?
Để tìm sự giải thoát, hãy tải xuống Bản đồ tư duy về đồng thời Python MIỄN PHÍ của tôi
mang đi
Trong hướng dẫn này, bạn đã khám phá ra cách kiểm tra đồng thời trạng thái của các trang web trên internet bằng cách sử dụng nhóm luồng trong Python