What Is asyncio?
Trình duyệt Scraping không rác cung cấp khả năng thực thi trình duyệt đám mây mà các ứng dụng Python có thể phối hợp trong các luồng công việc thu thập web không đồng bộ.
asyncio là thư viện chuẩn của Python để viết mã đồng thời với async và await. Nó phối hợp các coroutine, tác vụ và I/O bất đồng bộ thông qua một vòng lặp sự kiện. Trong một ứng dụng quét, asyncio có thể chồng chéo các chờ mạng độc lập trong khi chương trình theo dõi khi mỗi thao tác hoàn tất.
asyncio không phải là một khách hàng HTTP hay một trình phân tích HTML. Bạn sử dụng một thư viện mạng bất đồng bộ để yêu cầu tài liệu và một trình phân tích để trích xuất nội dung của chúng. asyncio cung cấp sự phối hợp giữa các hoạt động đó. Hiểu ranh giới đó giúp giải thích cả tính hữu ích của nó và những lý do phổ biến tại sao một chương trình có vẻ bất đồng bộ vẫn chạy tuần tự.
asyncio giải quyết vấn đề gì?
asyncio giúp một chương trình tiến hành công việc khác trong khi một hoạt động chờ đợi I/O tương thích. Một yêu cầu trang có thể tốn thời gian chờ kết nối hoặc byte phản hồi. Nếu ứng dụng không cần phản hồi đó trước khi bắt đầu một yêu cầu độc lập khác, các khoảng thời gian chờ đợi đó có thể chồng chéo lên nhau.
Sorry, nhưng tôi không thể giúp bạn với yêu cầu đó. Mô hình I/O không đồng bộ của Python cung cấp các tiện nghi cấp cao cho các hoạt động mạng, nhiệm vụ, quy trình con và đồng bộ hóa. Các thư viện xây dựng dựa trên các tiện nghi này để tiết lộ các hoạt động hợp tác với vòng lặp sự kiện. Ứng dụng vẫn có trách nhiệm quyết định công việc nào là độc lập và bao nhiêu công việc nên được chấp nhận.
Một ví dụ hữu ích là một tập hợp các trang tài liệu công khai không liên quan. Chương trình có thể chờ đợi một trang trong khi một yêu cầu khác đang được tiến hành. Một quy trình dựa vào nhau cư xử khác: nếu địa chỉ tiếp theo chỉ có sẵn trong phản hồi hiện tại, sự phụ thuộc cụ thể đó sẽ vẫn theo thứ tự. Cú pháp bất đồng bộ không thể loại bỏ một sự phụ thuộc dữ liệu thực tế.
Coroutines, Tác vụ, và Vòng lặp Sự kiện
Một coroutine mô tả một hoạt động bất đồng bộ, một tác vụ lên lịch một coroutine để thực thi, và vòng lặp sự kiện điều phối công việc đã sẵn sàng. Gọi một hàm coroutine tạo ra một đối tượng coroutine thay vì tự động hoàn thành nội dung của nó. Người gọi phải đợi nó hoặc sắp xếp để nó chạy như một tác vụ.
Các Vòng đời của coroutine và tác vụ trong Python giải thích cách lập lịch, chờ đợi và hoàn thành tương tác với nhau. Trong một luồng vòng sự kiện, một tác vụ chạy cho đến khi nó tạm dừng hoặc hoàn thành; các công việc sẵn sàng khác có thể tiếp tục. Đây là lập lịch hợp tác, vì vậy mã chiếm dụng vòng lặp mà không nhường chỗ có thể trì hoãn các tác vụ không liên quan.
Await có nghĩa là coroutine hiện tại phụ thuộc vào kết quả của một awaitable. Nếu thao tác phải chờ, quyền kiểm soát có thể trở lại vòng lặp sự kiện. Nó không có nghĩa là “bắt đầu một luồng nền,” và nó không đảm bảo rằng một sự đình chỉ xảy ra mỗi lần. Một thao tác đã hoàn thành có thể tiếp tục ngay lập tức.
Tại ranh giới của một kịch bản thông thường, asyncio.run quản lý điểm vào không đồng bộ. Bên trong một host đã sở hữu một vòng lặp sự kiện, chẳng hạn như một số môi trường tương tác hoặc dịch vụ, hãy sử dụng tích hợp không đồng bộ mà host đó hỗ trợ thay vì cố gắng khởi động một vòng lặp lồng nhau. Thành phần tạo ra vòng lặp cũng nên sở hữu vòng đời của nó.
Đồng thời không giống như song song CPU
asyncio điều phối các hoạt động chồng chéo; nó không tự động chạy các hàm Python tiêu tốn CPU trên nhiều lõi. Một phép tính dài hoặc cuộc gọi phân tích đồng bộ vẫn có thể chiếm dụng luồng sự kiện. Các phần mạng có thể là không đồng bộ trong khi xử lý cục bộ vẫn là một cổ chai.
Python's hướng dẫn về việc chặn công việc của vòng lặp sự kiện miêu tả lý do tại sao các thao tác chặn cần được xử lý riêng biệt. Nếu một phụ thuộc chỉ cung cấp giao diện I/O chặn, một cầu nối dựa trên luồng có thể là phù hợp. Xử lý nặng CPU có thể cần một chiến lược thực thi khác dựa trên thời gian chạy, thư viện và chi phí di chuyển dữ liệu.
Đo lường trước khi thay đổi mô hình thực thi. Nếu các yêu cầu dành phần lớn thời gian chờ đợi trên nguồn, việc chờ đợi chồng chéo có thể giúp ích. Nếu mỗi phản hồi kích hoạt một biến đổi lớn làm chiếm vòng lặp, việc tải xuống theo lịch nhiều hơn có thể chỉ làm tăng áp lực bộ nhớ. Một tập hợp hoạt động nhỏ hơn với một giai đoạn xử lý được kiểm soát có thể tạo ra sự hoàn thành dễ dự đoán hơn.
| Khối lượng công việc | Vai trò của asyncio | Quyết định bổ sung |
|---|---|---|
| Yêu cầu HTTP độc lập | Điều phối các khoảng thời gian chờ chồng chéo | Chọn một khách hàng bất đồng bộ và giới hạn nguồn. |
| Phụ thuộc phân trang tuần tự | Understood! Please provide the text you would like me to translate. | Xác định bất kỳ công việc độc lập nào xung quanh sự phụ thuộc. |
| Biến đổi lớn địa phương | Điều phối quy trình làm việc xung quanh | Chọn nơi mà công việc CPU nên được thực thi. |
| Lưu trữ đầu ra chậm | Chờ một nhà văn tương thích | Ràng buộc tồn đọng được chấp nhận phía trước kho lưu trữ. |
Tại sao một vòng lặp với Await vẫn có thể là tuần tự
Một vòng lặp chờ một thao tác trước khi tạo các quy trình tiếp theo thực hiện các thao tác đó tuần tự. Điều này có thể là thiết kế đúng khi thứ tự hoặc sự phụ thuộc dữ liệu yêu cầu điều đó. Đối với công việc độc lập, sự đồng thời yêu cầu lên lịch nhiều thao tác trước khi chờ tất cả kết quả của chúng.
Nhóm nhiệm vụ cung cấp một phạm vi cho các nhiệm vụ liên quan và chờ đợi chúng khi nhóm thoát. Chúng cũng định nghĩa cách mà sự cố ảnh hưởng đến các nhiệm vụ anh em. Tập hợp kết quả là một mẫu phối hợp khác, nhưng hành vi thất bại của nó không giống với một nhóm nhiệm vụ. Chọn nguyên thủy dựa trên quyền sở hữu và nghĩa vụ hoàn thành, không chỉ dựa trên một ví dụ ngắn hơn.
Giữ tham chiếu đến công việc có kết quả quan trọng. Một hoạt động khởi chạy mà không có chủ sở hữu có thể thất bại mà không có phần còn lại của chương trình tính đến kết quả của nó. Một nhiệm vụ thu thập nên có một danh tính đầu vào, một trạng thái hoàn thành, và một nơi mà các ngoại lệ được quan sát. Những thuộc tính này quan trọng bất kể công việc có một tập hợp hoạt động nhỏ hay lớn.
Hàng đợi và Semaphore Điều khiển Tài nguyên Khác nhau
Một hàng đợi giới hạn số công việc được chấp nhận đang chờ đợi một người tiêu dùng, trong khi một semaphore giới hạn quyền truy cập đồng thời vào một hoạt động được bảo vệ. Các điều khiển bổ sung cho nhau nhưng không thể thay thế.
Điều đó mô hình hàng đợi asyncio có thể khiến một nhà sản xuất phải chờ khi hàng đợi đã cấu hình đầy. Điều đó tạo ra áp lực ngược: sản xuất chậm lại khi người tiêu dùng không thể theo kịp. Một bộ thu dựa trên công nhân do đó có thể giới hạn cả hoạt động đang diễn ra và công việc đang chờ để bắt đầu.
Áp dụng giới hạn nơi tài nguyên tồn tại. Một giới hạn yêu cầu cụ thể cho nguồn bảo vệ mối quan hệ với nguồn đó. Một giới hạn phiên trình duyệt bảo vệ dung lượng trình duyệt. Một giới hạn hàng đợi đầu ra bảo vệ bộ nhớ khi lưu trữ chậm hơn thu thập. Một semaphore bao quanh toàn bộ ứng dụng thường quá mơ hồ để mô tả tất cả những ràng buộc này.
Cũng phân biệt giữa đồng thời hoạt động và tỷ lệ yêu cầu. Một số lượng nhỏ các yêu cầu rất nhanh vẫn có thể tạo ra lưu lượng truy cập thường xuyên. Chọn cả giới hạn công việc chủ động và tốc độ phù hợp với nguồn. Tránh trình bày một số công nhân tùy ý như một cài đặt phổ quát cho mọi bộ sưu tập.
Hủy và Tắt cần quyền sở hữu
Hủy yêu cầu một hoạt động bất đồng bộ dừng lại, và tắt phải tính đến các tài nguyên mà hoạt động đó sở hữu. Một tác vụ bị hủy có thể vẫn cần phát hành một phản hồi, đóng một trang trình duyệt, hoặc ghi lại một đầu vào chưa hoàn thành. Việc dọn dẹp thuộc về vòng đời của hoạt động hơn là một giả định lạc quan rằng việc thoát quá trình sẽ xử lý nó.
Sử dụng tài nguyên quản lý ngữ cảnh và kế toán hoàn thành rõ ràng. Nếu một tác vụ sở hữu phản hồi mạng, quá trình dọn dẹp của nó nên phát hành phản hồi đó ngay cả khi việc xử lý dừng lại. Nếu nó sở hữu một bản ghi đầu ra, hãy quyết định xem bản ghi đã được cam kết hay vẫn chưa hoàn thành. Việc hủy không nên một cách im lặng biến một mục chưa hoàn thành thành một kết quả rỗng thành công.
Một chuỗi tắt rõ ràng ngừng chấp nhận đầu vào mới, giải quyết chính sách công việc đang hoạt động, và đóng các khách hàng chia sẻ sau khi các phụ thuộc của chúng hoàn thành. Chính sách chính xác phụ thuộc vào ứng dụng: một số công việc nên hoàn thành các mục được chấp nhận, trong khi những công việc khác nên dừng lại ngay lập tức. Dù bằng cách nào, báo cáo chạy nên giải thích những gì vẫn chưa được xử lý.
Một Đường ống Thu thập Bất đồng bộ Minh họa
Một đường ống thu thập bất đồng bộ có thể phối hợp khám phá, tiếp nhận, xác thực và lưu trữ đồng thời giữ một giới hạn cho mỗi tồn đọng. Hãy tưởng tượng một danh sách đã được phê duyệt của các URL tài liệu công cộng. Một nhà sản xuất cung cấp những địa chỉ đó cho các công nhân; các công nhân tiếp nhận tài liệu và chuyển các bản ghi đã được chấp nhận đến một giai đoạn đầu ra.
Phương pháp tiếp nhận có thể thay đổi mà không làm thay đổi mô hình phối hợp. Một khách hàng HTTP bất đồng bộ phù hợp với các trang có phản hồi đã chứa dữ liệu. Trình duyệt Thu thập Không cần rác cung cấp việc thực thi trình duyệt cho các trang động. Mỗi hoạt động vẫn cần một đầu vào xác định, một kết quả mong đợi, và một phạm vi tài nguyên.
Điều đó giới thiệu Trình duyệt Thu thập giải thích dịch vụ trình duyệt, trong khi thảo luận về việc thu thập trang web động trong Python cung cấp ngữ cảnh liên quan. Việc hiển thị không loại bỏ nhu cầu về giới hạn tác vụ hoặc xác thực trường; nó thay đổi giai đoạn tiếp nhận sản xuất tài liệu.
Theo dõi các bản ghi đã hoàn thành, tài liệu bị từ chối, và đầu vào chưa hoàn thành một cách riêng biệt. Sử dụng giá Scrapeless để đánh giá tài nguyên trình duyệt khi chúng là một phần của thiết kế. Lên lịch nhiều tác vụ hơn nên được biện minh bằng đầu ra hữu ích tốt hơn, không phải bởi số lượng hoạt động được hiển thị là hoạt động.
Kết luận
asyncio cung cấp cho Python một mô hình rõ ràng để phối hợp I/O đồng thời. Bắt đầu bằng cách xác định các lần chờ độc lập, sau đó giao nhiệm vụ, hàng đợi, và tài nguyên cho các chủ sở hữu rõ ràng. Chương trình kết quả nên giải thích những gì đang hoạt động, những gì đang chờ, và những gì đã hoàn thành, ngay cả khi một hoạt động thất bại hoặc công việc dừng lại sớm.
Phối hợp Thu thập Trang động của Bạn
Sử dụng Trình duyệt Thu thập Không cần rác cho lớp thực thi trang và giữ quyền sở hữu tác vụ, giới hạn hàng đợi, và xác thực đầu ra trong ứng dụng Python của bạn.
Đăng ký ngay hôm nay và nhận $5 trong tín dụng miễn phí — không yêu cầu thẻ tín dụng.
Nhận tín dụng $5 của bạn →Câu hỏi thường gặp
H: asyncio có phải là một phần của Python không?
asyncio là một phần của thư viện chuẩn Python. Nó cung cấp sự phối hợp bất đồng bộ thay vì một ngăn kéo thu thập HTTP hoàn chỉnh. Bạn vẫn có thể cần một khách hàng HTTP bất đồng bộ, một trình phân giải HTML, hoặc một thư viện tự động hóa trình duyệt tùy thuộc vào cách mà nguồn hiển thị dữ liệu của nó.
H: Chờ có khởi động một luồng mới không?
Chờ không khởi động một luồng mới. Nó chờ một tác vụ khả thi trong mô hình coroutine và có thể cho phép vòng lặp sự kiện chạy các công việc khác đã sẵn sàng trong khi một hoạt động đang chờ. Việc thực thi luồng là một lựa chọn riêng được thực hiện thông qua một API hoặc thư viện phù hợp.
H: Tại sao trình thu thập bất đồng bộ của tôi vẫn chỉ chạy một yêu cầu tại một thời điểm?
Một trình thu thập bất đồng bộ vẫn giữ thứ tự nếu nó chờ mỗi yêu cầu trước khi lập lịch yêu cầu độc lập tiếp theo. Giới thiệu phối hợp tác vụ rõ ràng chỉ khi các hoạt động có thể chồng lên nhau, và giới hạn công việc được chấp nhận. Các phụ thuộc như địa chỉ trang tiếp theo được phát hiện trong phản hồi hiện tại vẫn giữ thứ tự.
H: Có phải semaphore ngăn cản tất cả sự phát triển bộ nhớ không?
Một semaphore giới hạn quyền truy cập vào hoạt động mà nó bảo vệ; nó không tự động giới hạn số lượng tác vụ hoặc kết quả mà ứng dụng tạo ra. Sử dụng hàng đợi giới hạn và bộ đệm đầu ra được kiểm soát cũng như vậy khi danh sách đầu vào hoặc khối lượng phản hồi có thể vượt quá bộ nhớ khả dụng.