Python tải xuống tất cả các tệp từ url
Điều này có thể tăng tốc đáng kể quá trình tải xuống so với việc tải xuống từng tệp một cách tuần tự. Show
Trong hướng dẫn này, bạn sẽ khám phá cách tải xuống đồng thời nhiều tệp từ internet bằng các luồng trong Python Sau khi hoàn thành hướng dẫn này, bạn sẽ biết
Hãy đi sâu vào Mục lục
Cách tải xuống tệp từ Internet (từ từ)Tải xuống tệp từ internet là một nhiệm vụ phổ biến Ví dụ
Nếu bạn không biết cách viết mã, thì bạn có thể giải quyết vấn đề này bằng cách tải trang web trong trình duyệt, sau đó nhấp lần lượt vào từng tệp để lưu vào ổ cứng của bạn Đối với nhiều tệp, quá trình này có thể mất nhiều thời gian để nhấp vào từng tệp trước tiên và sau đó đợi tất cả các lượt tải xuống hoàn tất Rất may, chúng tôi là nhà phát triển, vì vậy chúng tôi có thể viết một tập lệnh để trước tiên khám phá tất cả các tệp trên trang web để tải xuống, sau đó tải xuống và lưu trữ tất cả chúng cục bộ Một số ví dụ về các trang web liệt kê các tệp mà chúng tôi có thể tải xuống các tệp bao gồm
Trong các ví dụ này, có một trang web HTML duy nhất cung cấp các liên kết tương đối đến các tệp được lưu trữ cục bộ Lý tưởng nhất là trang web sẽ liên kết đến nhiều tệp nhỏ hoặc có kích thước khiêm tốn và bản thân máy chủ sẽ cho phép nhiều kết nối từ mỗi máy khách Điều này có thể không phải lúc nào cũng đúng vì hầu hết các máy chủ đều giới hạn số lượng kết nối trên mỗi máy khách là 10 hoặc thậm chí 1 để ngăn chặn các cuộc tấn công từ chối dịch vụ Chúng tôi có thể phát triển một chương trình để tải xuống từng tệp một Có một vài phần của chương trình này;
Hãy xem lần lượt từng phần Ghi chú. chúng tôi sẽ chỉ thực hiện xử lý lỗi cơ bản nhất. Nếu bạn thay đổi URL mục tiêu, bạn có thể cần điều chỉnh mã cho các chi tiết cụ thể của HTML và các tệp bạn muốn tải xuống Tải xuống tệp URLBước đầu tiên là tải xuống một tệp được chỉ định bởi một URL Có nhiều cách để tải xuống một URL trong Python. Trong trường hợp này, chúng ta sẽ sử dụng hàm urlopen() để mở . read() function to download the contents of the file into memory. Để đảm bảo kết nối tự động đóng sau khi chúng tôi tải xuống xong, chúng tôi sẽ sử dụng trình quản lý ngữ cảnh, e. g. từ khóa với . Bạn có thể tìm hiểu thêm về cách mở và đọc từ các kết nối URL trong API Python tại đây
Hàm download_url() bên dưới thực hiện điều này, . 1 2 3 4 5 6 # tải tệp từ một URL, trả về nội dung của tệp đã tải xuống def download_url(đường dẫn url): # mở kết nối với máy chủ với urlopen(đường dẫn url) as connection: # đọc nội dung của url dưới dạng byte và gửi lại trả lại kết nối. đọc() Chúng tôi sẽ sử dụng chức năng này để tải xuống trang HTML liệt kê các tệp và tải xuống nội dung của từng tệp được liệt kê Một cải tiến về chức năng này là thêm thời gian chờ trên kết nối, có thể sau vài giây. Điều này sẽ đưa ra một ngoại lệ nếu máy chủ không phản hồi và là một cách thực hành tốt khi mở kết nối với máy chủ từ xa Phân tích cú pháp HTML cho tệp để tải xuốngKhi trang HTML của các URL được tải xuống, chúng tôi phải phân tích cú pháp trang đó và trích xuất tất cả các liên kết đến tệp Tôi khuyên dùng thư viện BeautifulSoup Python bất cứ lúc nào tài liệu HTML cần được phân tích cú pháp Nếu bạn chưa quen với BeautifulSoup, bạn có thể cài đặt nó dễ dàng bằng trình quản lý gói Python của mình, chẳng hạn như pip 1 cài đặt pip beautifulsoup4 Đầu tiên, chúng ta phải giải mã dữ liệu thô được tải xuống thành văn bản ASCII Điều này có thể đạt được bằng cách gọi decode() function on the string of raw data and specifying a standard text format, such as UTF-8. 1 2 3 .. . # giải mã nội dung được cung cấp dưới dạng văn bản ascii html = nội dung. giải mã('utf-8') Tiếp theo, chúng ta có thể phân tích cú pháp văn bản của tài liệu HTML bằng BeautifulSoup bằng trình phân tích cú pháp mặc định Bạn nên sử dụng trình phân tích cú pháp tinh vi hơn hoạt động giống nhau trên tất cả các nền tảng, nhưng trong trường hợp này, sẽ sử dụng trình phân tích cú pháp mặc định vì nó không yêu cầu bạn cài đặt thêm bất kỳ thứ gì 1 2 3 .. . # phân tích cú pháp tài liệu tốt nhất có thể súp = Súp đẹp(html, 'html.parser') Sau đó, chúng tôi có thể truy xuất tất cả thẻ HTML từ tài liệu vì những thẻ này sẽ chứa URL cho các tệp chúng tôi . 1 2 3 .. . # find all all of the tags in the document tags = súp. find_all('a') Sau đó, chúng tôi có thể duyệt qua tất cả các thẻ được tìm thấy và truy xuất nội dung của thuộc tính href trên mỗi thẻ, e. g. lấy các liên kết đến các tệp từ mỗi thẻ. Nếu thẻ không chứa thuộc tính href (có thể là số lẻ, e. g. một liên kết neo), thì chúng ta sẽ hướng dẫn hàm trả về None . Điều này có thể nằm trong phần hiểu danh sách, cung cấp cho chúng tôi danh sách các URL tới các tệp để tải xuống và có thể một số Không cógiá trị1 2 3 .. . # nhận tất cả các giá trị href (liên kết) hoặc Không có nếu không có (không chắc) return [t. lấy('href', None) for t in atags] Liên kết tất cả những thứ này lại với nhau, get_urls_from_html() . 1 2 3 4 5 6 7 8 9 10 # decode downloaded html and extract all links def get_urls_from_html(nội dung): # giải mã nội dung được cung cấp dưới dạng văn bản ascii html = nội dung. giải mã('utf-8') # phân tích cú pháp tài liệu tốt nhất có thể súp = Súp đẹp(html, 'html.parser') # tìm tất cả tags = súp. find_all('a') # nhận tất cả các giá trị href (liên kết) hoặc Không có nếu không có (không chắc) return [t. lấy('href', None) for t in atags] Chúng tôi sẽ sử dụng chức năng này để trích xuất tất cả các tệp từ trang HTML liệt kê các tệp chúng tôi muốn tải xuống Lưu tải xuống tệp cục bộChúng tôi biết cách tải xuống tệp và nhận liên kết từ HTML. Một phần quan trọng khác mà chúng tôi cần là lưu các URL đã tải xuống vào các tệp cục bộ Điều này có thể được thực hiện bằng cách sử dụng mở() . Chúng tôi sẽ mở tệp ở chế độ ghi và định dạng nhị phân, vì chúng tôi có thể sẽ tải xuống. tệp zip hoặc tương tự Giống như với việc tải xuống các URL ở trên, chúng tôi sẽ sử dụng trình quản lý ngữ cảnh (từ khóa với ) để đảm bảo rằng kết nối tới tệp đã được đóng . Hàm save_file() bên dưới thực hiện điều này, . 1 2 3 4 5 6 # lưu nội dung được cung cấp vào đường dẫn cục bộ def save_file(đường dẫn, data): # mở tệp cục bộ để ghi với mở(đường dẫn, 'wb') as file: # ghi tất cả dữ liệu được cung cấp vào tệp tệp. ghi(dữ liệu) Bạn có thể muốn thêm xử lý lỗi ở đây, chẳng hạn như không ghi được hoặc trường hợp tệp đã tồn tại cục bộ Chúng ta cần thực hiện một số công việc để có thể sử dụng chức năng này Ví dụ: chúng tôi cần kiểm tra xem chúng tôi có liên kết nào từ thuộc tính href không (rằng đó không phải là None ) và URL đó . g. có một. nén hoặc. phần mở rộng gz). Đây là một số kiểm tra hoặc lọc lỗi cơ bản đối với các loại URL mà chúng tôi muốn tải xuống. 1 2 3 4 5 6 7 .. . # bỏ qua url xấu hoặc tên tệp xấu nếu liên kết là Không có hoặc link == '../'. trả lại # kiểm tra không có phần mở rộng tập tin nếu không (liên kết[-4] == '.' hoặc liên kết[- . '] == '.' ). trả lại Các trang HTML liệt kê các tệp thường bao gồm các liên kết tương đối thay vì liên kết tuyệt đối Tức là, các liên kết đến các tệp được tải xuống sẽ liên quan đến tệp HTML. Chúng ta phải chuyển đổi chúng thành liên kết tuyệt đối (với http. //. ở phía trước) để có thể tải xuống tệp. Chúng ta có thể sử dụng chức năng urljoin() từ . Mô-đun urllib.phân tích cú pháp để chuyển đổi bất kỳ URL tương đối nào thành URL tuyệt đối để chúng tôi có thể tải tệp xuống. 1 2 3 .. . # chuyển đổi liên kết tương đối thành liên kết tuyệt đối vô lý = urljoin(url, link) Sau đó, bạn có thể tải xuống URL tuyệt đối bằng cách sử dụng download_url() function developed above. 1 2 3 .. . # tải xuống nội dung của tệp dữ liệu = download_url(bất ngờ) Tiếp theo, chúng ta cần xác định tên của tệp từ URL mà chúng ta sẽ lưu cục bộ. Điều này có thể đạt được bằng cách sử dụng hàm tên cơ sở() từ os.đường dẫn mô-đun. 1 2 3 .. . # lấy tên tệp tên tệp = tên cơ sở(lố) Sau đó, chúng ta có thể xác định đường dẫn cục bộ để lưu tệp bằng cách kết hợp đường dẫn thư mục cục bộ với tên tệp. Hàm tham gia() từ hệ điều hành. mô-đun đường dẫn sẽ thực hiện việc này cho chúng tôi một cách chính xác dựa trên nền tảng của chúng tôi (Unix, Windows, MacOS). 1 2 3 .. . # xây dựng đường dẫn đầu ra đường ra = tham gia(đường, filename) Bây giờ chúng tôi có đủ thông tin để lưu tệp bằng cách gọi save_file() function. 1 2 3 .. . # lưu vào tập tin save_file(đường ra, dữ liệu) Hàm download_url_to_file() bên dưới liên kết tất cả . Nó tải xuống URL, lưu cục bộ dưới dạng tệp và trả về liên kết tương đối và đường dẫn tệp cục bộ trong một bộ dữ liệu. Nếu tệp không được lưu, chúng tôi trả về một bộ chỉ với URL tương đối và Không có cho đường dẫn cục bộ Chúng tôi chọn trả lại một số thông tin từ chức năng này để người gọi có thể báo cáo tiến độ về việc tải xuống từng tệp thành công hay thất bại 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # tải một tệp xuống thư mục cục bộ def download_url_to_file(url, link, path): # bỏ qua url không hợp lệ hoặc tên tệp không hợp lệ nếu liên kết là Không có or link == '../'. trả lại (liên kết, None) # kiểm tra xem không có phần mở rộng tệp nào nếu không (liên kết[-4] == '.' hoặc liên kết[- . '] == '.' ). trả lại (liên kết, None) # chuyển đổi liên kết tương đối thành liên kết tuyệt đối vô lý = liên kết url(url, link) # tải xuống nội dung của tệp dữ liệu = download_url(absurl) # lấy tên tệp tên tệp = tên cơ sở(absurl) # xây dựng đường dẫn đầu ra đường ngoài = tham gia(path, filename) # lưu vào tệp save_file(đường ra, data) # kết quả trả về return (link, outpath) Phối hợp quá trình tải xuốngCuối cùng, chúng ta cần điều phối quá trình tổng thể Trước tiên, phải tải xuống URL của trang HTML bằng cách sử dụng download_url() function defined above. 1 2 3 .. . # tải xuống trang web html dữ liệu = download_url(url) Tiếp theo, chúng ta cần tạo bất kỳ thư mục nào trên đường dẫn cục bộ mà chúng ta đã chọn để lưu trữ các tệp cục bộ. Chúng ta có thể làm điều này bằng cách sử dụng hàm makedirs() từ os module and ignore the case where the directories already exist. 1 2 3 .. . # tạo thư mục cục bộ để lưu tệp makedirs(đường dẫn, exist_ok=True) Tiếp theo, chúng tôi sẽ truy xuất danh sách tất cả các liên kết tương đối đến các tệp được liệt kê trên trang HTML bằng cách gọi get_urls_from_html() function, and report how many links were found. 1 2 3 4 5 .. . # phân tích cú pháp html và truy xuất tất cả các url href được liệt kê liên kết = get_urls_from_html(dữ liệu) # báo cáo tiến độ in(f'Tìm thấy liên kết {len(links)} trong {url}'<) Cuối cùng, chúng tôi sẽ duyệt qua danh sách các liên kết, tải từng liên kết xuống một tệp cục bộ bằng lệnh gọi tới download_url_to_file() function, then report the success or failure of the download. 1 2 3 4 5 6 7 8 9 10 .. . # tải xuống từng tệp trên trang web đối với liên kết trong liên kết. # tải url xuống tệp cục bộ liên kết, đường ra = download_url_to_file(url, link, path) # kiểm tra liên kết đã bị bỏ qua nếu đường ra là Không: in(f'>đã bỏ qua {link}) khác. in(f'Đã tải {link} xuống) Liên kết cái này lại với nhau, hàm download_all_files() . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # tải xuống tất cả các tệp trên trang web được cung cấp theo đường dẫn được cung cấp def download_all_files(url, path): # tải xuống trang web html dữ liệu = download_url(url) # tạo thư mục cục bộ để lưu tệp makedirs(đường dẫn, exist_ok=True) # phân tích cú pháp html và truy xuất tất cả href url được liệt kê liên kết = get_urls_from_html(data) # tiến trình báo cáo print(f'Đã tìm thấy {len(links) # tải xuống từng tệp trên trang web cho liên kết trong liên kết: # tải url xuống tệp cục bộ liên kết, đường ra = download_url_to_file(url, link, path) # kiểm tra liên kết đã bị bỏ qua nếu đường ra là Không: in(f'>đã bỏ qua {link}) khác. in(f'Đã tải {link} xuống) Hoàn thành ví dụBây giờ chúng tôi có tất cả các yếu tố để tải xuống tất cả các tệp được liệt kê trên trang web HTML Hãy thử nghiệm nó Chọn một trong các URL được liệt kê ở trên và sử dụng các chức năng mà chúng tôi đã phát triển để tải xuống tất cả các tệp được liệt kê Trong trường hợp này, tôi sẽ chọn tải xuống tất cả các sửa đổi bot do bên thứ ba phát triển cho trò chơi máy tính Quake 1 1 2 3 .. . # url của trang html liệt kê tất cả các tệp để tải xuống URL = 'https. //www. cai nghiện. com/files/idgames2/quakec/bots/' Dưới đây là một ví dụ về giao diện của trang web này Chúng tôi sẽ lưu tất cả các tệp trong thư mục cục bộ trong thư mục con tmp/ . 1 2 3 .. . # thư mục cục bộ để lưu tất cả các tệp trên trang html ĐƯỜNG = 'tmp' Sau đó, chúng ta có thể gọi hàm download_all_files() . 1 2 3 .. . # tải xuống tất cả các tệp trên trang web html download_all_files(URL, PATH) Liên kết điều này lại với nhau, ví dụ hoàn chỉnh về việc tải xuống tất cả các tệp trên trang web HTML đượ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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 #Trăn Siêu Nhanh. com # tải xuống tuần tự tất cả các tệp từ một trang web from os import makedirs from os. đường dẫn nhập tên cơ sở from os. path import join từ urllib. yêu cầu nhập urlopen từ urllib. phân tích cú pháp nhập urljoin từ bs4 nhập BeautifulSoup
# tải tệp từ một URL, trả về nội dung của tệp đã tải xuống def download_url(đường dẫn url): # mở kết nối với máy chủ với urlopen(đường dẫn url) as connection: # đọc nội dung của url dưới dạng byte và gửi lại trả lại kết nối. đọc()
# decode downloaded html and extract all links def get_urls_from_html(nội dung): # giải mã nội dung được cung cấp dưới dạng văn bản ascii html = nội dung. giải mã('utf-8') # phân tích cú pháp tài liệu tốt nhất có thể súp = Súp đẹp(html, 'html.parser') # tìm tất cả tags = súp. find_all('a') # nhận tất cả các giá trị href (liên kết) hoặc Không có nếu không có (không chắc) return [t. lấy('href', None) for t in atags]
# lưu nội dung được cung cấp vào đường dẫn cục bộ def save_file(đường dẫn, data): # mở tệp cục bộ để ghi với mở(đường dẫn, 'wb') as file: # ghi tất cả dữ liệu được cung cấp vào tệp tệp. ghi(dữ liệu)
# tải một tệp xuống thư mục cục bộ def download_url_to_file(url, link, path): # bỏ qua url không hợp lệ hoặc tên tệp không hợp lệ nếu liên kết là Không có or link == '../'. trả lại (liên kết, None) # kiểm tra xem không có phần mở rộng tệp nào nếu không (liên kết[-4] == '.' hoặc liên kết[- . '] == '.' ). trả lại (liên kết, None) # chuyển đổi liên kết tương đối thành liên kết tuyệt đối vô lý = liên kết url(url, link) # tải xuống nội dung của tệp dữ liệu = download_url(absurl) # lấy tên tệp tên tệp = tên cơ sở(absurl) # xây dựng đường dẫn đầu ra đường ngoài = tham gia(path, filename) # lưu vào tệp save_file(đường ra, data) # kết quả trả về return (link, outpath)
# tải xuống tất cả các tệp trên trang web được cung cấp theo đường dẫn được cung cấp def download_all_files(url, path): # tải xuống trang web html dữ liệu = download_url(url) # tạo thư mục cục bộ để lưu tệp makedirs(đường dẫn, exist_ok=True) # phân tích cú pháp html và truy xuất tất cả href url được liệt kê liên kết = get_urls_from_html(data) # tiến trình báo cáo print(f'Đã tìm thấy {len(links) # tải xuống từng tệp trên trang web cho liên kết trong liên kết: # tải url xuống tệp cục bộ liên kết, đường ra = download_url_to_file(url, link, path) # kiểm tra liên kết đã bị bỏ qua nếu đường ra là Không: in(f'>đã bỏ qua {link}) khác. in(f'Đã tải {link} xuống)
# url của trang html liệt kê tất cả các tệp để tải xuống URL = 'https. //www. cai nghiện. com/files/idgames2/quakec/bots/' # thư mục cục bộ để lưu tất cả các tệp trên trang html ĐƯỜNG = 'tmp' # tải xuống tất cả các tệp trên trang web html download_all_files(URL, PATH) Việc chạy ví dụ trước tiên sẽ tải xuống trang web HTML liệt kê tất cả các tệp, sau đó tải xuống từng tệp được liệt kê trên trang vào thư mục tmp/ . Quá trình này sẽ mất nhiều thời gian, có thể là 3-4 phút vì các tệp được tải xuống cùng một lúc Khi chương trình chạy, nó sẽ báo cáo tiến độ hữu ích Đầu tiên, nó nhận xét rằng 113 liên kết đã được tìm thấy trên trang và một số thư mục đã bị bỏ qua. Sau đó, nó báo cáo tên tệp và đường dẫn cục bộ của từng tệp được lưu 1 2 3 4 5 6 7 8 9 10 11 Đã tìm thấy 113 liên kết trong https. //www. cai nghiện. com/files/idgames2/quakec/bots/ > bỏ qua. / >đã bỏ qua bộ khử/ >bỏ qua máy gặt/ kẻ tấn công đã tải xuống. txt sang tmp/kẻ tấn công. txt kẻ tấn công đã tải xuống. zip vào tmp/kẻ tấn công. khóa kéo Đã tải xuống bgadm101. txt to tmp/bgadm101. txt Đã tải xuống bgadm101. nén vào tmp/bgadm101. khóa kéo Downloaded bgbot16. txt sang tmp/bgbot16. txt Downloaded bgbot16. nén vào tmp/bgbot16. zip ... How long did it take to run on your computer? Tiếp theo, chúng ta sẽ xem xét lớp ThreadPoolExecutor có thể được sử dụng để tạo nhóm luồng công nhân cho phép chúng ta tăng tốc . Chạ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 Cách tạo một nhóm chủ đề công nhân với ThreadPoolExecutorWe can use the ThreadPoolExecutor class to speed up the download of multiple files listed on an HTML webpage. Lớp ThreadPoolExecutor được cung cấp như một phần của đồng thời.tương lai để dễ dàng chạy các tác vụ đồng thời. Các ThreadPoolExecutor cung cấp nhóm chuỗi công nhân, khác với ProcessPoolExecutor cung cấp nhóm .Nói chung là, ThreadPoolExecutor nên được sử dụng cho các tác vụ liên kết với IO đồng thời, như tải xuống URL và ProcessPoolExecutor .Using the 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 chủ đềFirst, a ThreadPoolExecutor instance must be created.Theo mặc định, nó sẽ tạo ra một nhóm luồng bằng với số lõi CPU hợp lý trong hệ thống của bạ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 pool = ThreadPoolExecutor() 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 .. . # create a thread pool with 10 worker threads pool = ThreadPoolExecutor(max_workers=10) Gửi nhiệm vụ đến Thread PoolSau khi được tạo, chúng tôi 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 đối tượng Tương lai . Các Future là một lời hứa trả về kết quả từ nhiệm vụ (nếu có) và cung cấp cách xác định xem một nhiệm vụ cụ thể đã được hoàn thành hay chưa.1 2 3 .. . # gửi một nhiệm vụ future = pool. gửi(my_task, 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ả() . 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ả. function on the future object. It will wait until the result is available, if needed, or return immediately if the result is available. Ví dụ 1 2 3 .. . # get the result from a future result = future. kết quả() 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. futures module provides an 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. For example, we can use a list comprehension to submit the tasks and create the list of future objects 1 2 3 .. . # submit all tasks into the thread pool and create a list of futures tương lai = [nhóm. gửi(my_func, nhiệm vụ) for task in tasks] Then get results for tasks as they complete in a for loop 1 2 3 4 5 6 .. . # 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 for future in as_completed(futures). # lấy kết quả result = future. kết quả() # làm điều gì đó với kết quả 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 .. . # shutdown the thread pool nhóm. tắt máy() An easier way to use the thread pool is via the context manager (the with keyword), which ensures it is closed automatically once we are finished with it. 1 2 3 4 5 6 7 8 9 10 .. . # tạo nhóm chủ đề với ThreadPoolExecutor(max_workers=10) as pool: # gửi nhiệm vụ tương lai = [nhóm. gửi(my_func, nhiệm vụ) for task in tasks] # nhận kết quả khi chúng có sẵn for future in as_completed(futures). # lấy kết quả result = future. 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 tải xuống URL của mình để tạo . Bối rối với API lớp ThreadPoolExecutor? Cách tải xuống nhiều tệp đồng thờiChương trình tải URL xuống tệp có thể được điều chỉnh để sử dụng ThreadPoolExecutor với rất ít thay đổi. Hàm download_all_files() hiện liệt kê danh sách . download_url_to_file() function for each. Có thể cập nhật vòng lặp này thành submit() tasks to a ThreadPoolExecutor , sau đó chúng ta có thể đợi các đối tượng trong tương lai thông qua lệnh gọi tới as_completed( . ) and report progress.Ví dụ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 .. . # tạo nhóm chủ đề công nhân với ThreadPoolExecutor(max_workers=20) as exe: # gửi tất cả tác vụ tải xuống tới chuỗi công nhân tương lai = [exe.gửi(download_url_to_file, url, link, path) for link in links] # báo cáo kết quả khi chúng có sẵn cho tương lai trong as_completed(futures): # truy xuất kết quả liên kết, đường ra = future.kết quả() # kiểm tra liên kết đã bị bỏ qua nếu đường ra là Không: in(f'>đã bỏ qua {link}) khác. in(f'Đã tải {link} xuống) Ở đây, chúng tôi sử dụng 20 luồng cho tối đa 20 kết nối đồng thời đến máy chủ lưu trữ tệp. Điều này có thể cần được điều chỉnh tùy thuộc vào số lượng kết nối đồng thời được hỗ trợ bởi máy chủ mà bạn muốn tải tệp xuống từ đó Phiên bản cập nhật của hàm download_all_files() . ThreadPoolExecutor is listed below. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # tải xuống tất cả các tệp trên trang web được cung cấp theo đường dẫn được cung cấp def download_all_files(url, path): # tải xuống trang web html dữ liệu = download_url(url) # tạo thư mục cục bộ để lưu tệp makedirs(đường dẫn, exist_ok=True) # phân tích cú pháp html và truy xuất tất cả href url được liệt kê liên kết = get_urls_from_html(data) # tiến trình báo cáo print(f'Đã tìm thấy {len(links) # tạo nhóm chuỗi công nhân với ThreadPoolExecutor(max_workers=20) as exe: # gửi tất cả tác vụ tải xuống tới chuỗi công nhân hợp đồng tương lai = [exe.gửi(download_url_to_file, url, link, path) for link in links] # báo cáo kết quả khi chúng có sẵn cho tương lai trong as_completed(futures): # truy xuất kết quả liên kết, đường ra = future.kết quả() # kiểm tra liên kết đã bị bỏ qua nếu đường ra là Không: in(f'>đã bỏ qua {link}) else. in(f'Đã tải {link} xuống) Liên kết điều này lại với nhau, ví dụ hoàn chỉnh về việc tải xuống đồng thời tất cả các bot quake 1 bằng cách sử dụng ThreadPoolExecutor đượ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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 #Trăn Siêu Nhanh. com # tải xuống tuần tự tất cả các tệp từ một trang web from os import makedirs from os. đường dẫn nhập tên cơ sở from os. path import join từ urllib. yêu cầu nhập urlopen từ urllib. phân tích cú pháp nhập urljoin từ đồng thời. tương lai nhập ThreadPoolExecutor từ đồng thời. tương lai nhập as_completed từ bs4 nhập BeautifulSoup
# tải tệp từ một URL, trả về nội dung của tệp đã tải xuống def download_url(đường dẫn url): # mở kết nối với máy chủ với urlopen(đường dẫn url) as connection: # đọc nội dung của url dưới dạng byte và gửi lại trả lại kết nối. đọc()
# decode downloaded html and extract all links def get_urls_from_html(nội dung): # giải mã nội dung được cung cấp dưới dạng văn bản ascii html = nội dung. giải mã('utf-8') # phân tích cú pháp tài liệu tốt nhất có thể súp = Súp đẹp(html, 'html.parser') # tìm tất cả tags = súp. find_all('a') # nhận tất cả các giá trị href (liên kết) hoặc Không có nếu không có (không chắc) return [t. lấy('href', None) for t in atags]
# lưu nội dung được cung cấp vào đường dẫn cục bộ def save_file(đường dẫn, data): # mở tệp cục bộ để ghi với mở(đường dẫn, 'wb') as file: # ghi tất cả dữ liệu được cung cấp vào tệp tệp. ghi(dữ liệu)
# tải một tệp xuống thư mục cục bộ def download_url_to_file(url, link, path): # bỏ qua url không hợp lệ hoặc tên tệp không hợp lệ nếu liên kết là Không có or link == '../'. trả lại (liên kết, None) # kiểm tra xem không có phần mở rộng tệp nào nếu không (liên kết[-4] == '.' hoặc liên kết[- . '] == '.' ). trả lại (liên kết, None) # chuyển đổi liên kết tương đối thành liên kết tuyệt đối vô lý = liên kết url(url, link) # tải xuống nội dung của tệp dữ liệu = download_url(absurl) # lấy tên tệp tên tệp = tên cơ sở(absurl) # xây dựng đường dẫn đầu ra đường ngoài = tham gia(path, filename) # lưu vào tệp save_file(đường ra, data) # kết quả trả về return (link, outpath)
# tải xuống tất cả các tệp trên trang web được cung cấp theo đường dẫn được cung cấp def download_all_files(url, path): # tải xuống trang web html dữ liệu = download_url(url) # tạo thư mục cục bộ để lưu tệp makedirs(đường dẫn, exist_ok=True) # phân tích cú pháp html và truy xuất tất cả href url được liệt kê liên kết = get_urls_from_html(data) # tiến trình báo cáo print(f'Đã tìm thấy {len(links) # tạo nhóm chuỗi công nhân với ThreadPoolExecutor(max_workers=20) as exe: # gửi tất cả tác vụ tải xuống tới chuỗi công nhân hợp đồng tương lai = [exe.gửi(download_url_to_file, url, link, path) for link in links] # báo cáo kết quả khi chúng có sẵn cho tương lai trong as_completed(futures): # truy xuất kết quả liên kết, đường ra = future.kết quả() # kiểm tra liên kết đã bị bỏ qua nếu đường ra là Không: in(f'>đã bỏ qua {link}) else. in(f'Đã tải {link} xuống)
# url của trang html liệt kê tất cả các tệp để tải xuống URL = 'https. //www. cai nghiện. com/files/idgames2/quakec/bots/' # thư mục cục bộ để lưu tất cả các tệp trên trang html ĐƯỜNG = 'tmp' # tải xuống tất cả các tệp trên trang web html download_all_files(URL, PATH) Chạy ví dụ trước tiên sẽ tải xuống và phân tích cú pháp trang HTML liệt kê tất cả các tệp cục bộ Mỗi tệp trên trang sau đó được tải xuống đồng thời, với tối đa 20 tệp được tải xuống cùng một lúc Điều này tăng tốc đáng kể tác vụ, mất 10-15 giây tùy thuộc vào kết nối internet của bạn, so với 3-4 phút cho phiên bản tuần tự. Đó là về tốc độ tăng tốc 33 lần Tiến trình được báo cáo như lần trước, nhưng chúng ta có thể thấy rằng các tệp được báo cáo không theo thứ tự Ở đây, chúng ta có thể thấy rằng càng nhỏ. txt kết thúc trước bất kỳ. tập tin zip 1 2 3 4 5 6 7 8 9 10 11 Đã tìm thấy 113 liên kết trong https. //www. cai nghiện. com/files/idgames2/quakec/bots/ > bỏ qua. / >đã bỏ qua bộ khử/ >bỏ qua máy gặt/ Đã tải xuống bgadm101. txt to tmp/bgadm101. txt kẻ tấn công đã tải xuống. txt sang tmp/kẻ tấn công. txt Downloaded bgbot16. txt sang tmp/bgbot16. txt Đã tải xuống bgbot20a. txt sang tmp/bgbot20a. txt Đã tải xuống borg12. txt sang tmp/borg12. txt Đã tải xuống bplayer2. txt sang tmp/bplayer2. txt ... How long did it take to run on your computer? 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 Tiện ích mở rộngPhần này liệt kê các ý tưởng để mở rộng hướng dẫn
Share your extensions in the comments below; it would be great to see what you come up with Choáng ngợp trước các API đồng thời của python? Đọc thêmPhầ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
I also recommend specific chapters from the following books
hướng dẫn
API
mang điTrong hướng dẫn này, bạn đã học cách tải xuống đồng thời nhiều tệp bằng cách sử dụng nhóm chuỗi công nhân trong Python. Bạn đã học Làm cách nào để tải xuống tất cả các tệp từ URL Python?Để tải xuống tệp từ một URL bằng Python, hãy làm theo ba bước sau. . Cài đặt mô-đun yêu cầu và nhập nó vào dự án của bạn sử dụng yêu cầu. get() để tải xuống dữ liệu đằng sau URL đó Ghi tệp vào một tệp trong hệ thống của bạn bằng cách gọi open() Làm cách nào để tải xuống dữ liệu từ URL trong Python?Khoa học dữ liệu thực tế sử dụng Python . Nhập mô-đun. yêu cầu nhập khẩu Nhận liên kết hoặc url. url = 'https. //www. Facebook. com/favicon. ico' r = yêu cầu. get(url, allow_redirects=True) Lưu nội dung với tên. mở Facebook. ico', 'wb'). nhà văn. nội dung) lưu tệp dưới dạng facebook. ico Tôi có thể sử dụng Python để tải xuống tệp từ trang web không?Requests là một thư viện HTTP linh hoạt trong python với nhiều ứng dụng khác nhau. Một trong những ứng dụng của nó là tải xuống tệp từ trang web bằng URL của tệp . Hoặc tải trực tiếp từ đây và cài đặt thủ công.
Làm cách nào để đọc tệp từ URL trong Python?5 cách để đọc tệp văn bản từ một URL . Phương pháp 1. sử dụng urllib. yêu cầu. urlopen() Phương pháp 2. sử dụng yêu cầu. được() Phương pháp 3. Sử dụng urllib3. Trình quản lý hồ bơi () Phương pháp 4. sử dụng urllib. yêu cầu. urlopen(). đọc (n) Phương pháp 5. sử dụng urllib. yêu cầu. urlopen(). đọc() |