import queue
import concurrent.futures
import urllib.request
URLS = ['https://w...content-available-to-author-only...s.com/',
'https://w...content-available-to-author-only...n.com/',
'https://e...content-available-to-author-only...j.com/',
'https://w...content-available-to-author-only...o.uk/',
'https://s...content-available-to-author-only...n.com/',
'https://google.com',
'https://p...content-available-to-author-only...n.org',
]
def load_url(url, timeout, q_success, q_fail):
""" Загрузить страницу по url, результат положить в очереди """
try:
with urllib.request.urlopen(url, timeout=timeout) as conn:
data = conn.read()
q_success.put_nowait((url, data))
return data
except Exception as exc:
q_fail.put_nowait((url, exc))
q_success = queue.Queue()
q_fail = queue.Queue()
# Этот контексный менеджер позволяет создать пул тредов, которые будут выполнять задания
# Треды будут созданы и завершены корректно, вся работа на менеждере
# Пул штука очень полезная, если у нас будет 100 url, очень плохая идея запускать 100 тредов
# и выполнять их одновременно.
with concurrent.futures.ThreadPoolExecutor(max_workers=13) as executor:
for url in URLS:
executor.submit(load_url, url, 5, q_success, q_fail)
print(f"\n Sucessfully loaded: {q_success.qsize()} url(s)")
while q_success.qsize():
url, data = q_success.get()
print(f"url [{url}], content size: {len(data)}")
print(f"\n Failed urls: {q_fail.qsize()} url(s)")
while q_fail.qsize():
url, exc = q_fail.get()
print(f"url [{url}], exception: {exc}")
aW1wb3J0IHF1ZXVlCmltcG9ydCBjb25jdXJyZW50LmZ1dHVyZXMKaW1wb3J0IHVybGxpYi5yZXF1ZXN0CgpVUkxTID0gWydodHRwczovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnMuY29tLycsCiAgICAgICAgJ2h0dHBzOi8vdy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4ubi5jb20vJywKICAgICAgICAnaHR0cHM6Ly9lLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5qLmNvbS8nLAogICAgICAgICdodHRwczovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLm8udWsvJywKICAgICAgICAnaHR0cHM6Ly9zLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5uLmNvbS8nLAogICAgICAgICdodHRwczovL2dvb2dsZS5jb20nLAogICAgICAgICdodHRwczovL3AuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLm4ub3JnJywKICAgICAgICBdCgpkZWYgbG9hZF91cmwodXJsLCB0aW1lb3V0LCBxX3N1Y2Nlc3MsIHFfZmFpbCk6CiAgICAiIiIg0JfQsNCz0YDRg9C30LjRgtGMINGB0YLRgNCw0L3QuNGG0YMg0L/QviB1cmwsINGA0LXQt9GD0LvRjNGC0LDRgiDQv9C+0LvQvtC20LjRgtGMINCyINC+0YfQtdGA0LXQtNC4ICIiIgogICAgdHJ5OgogICAgICAgIHdpdGggdXJsbGliLnJlcXVlc3QudXJsb3Blbih1cmwsIHRpbWVvdXQ9dGltZW91dCkgYXMgY29ubjoKICAgICAgICAgICAgZGF0YSA9IGNvbm4ucmVhZCgpCiAgICAgICAgICAgIHFfc3VjY2Vzcy5wdXRfbm93YWl0KCh1cmwsIGRhdGEpKQogICAgICAgICAgICByZXR1cm4gZGF0YQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBleGM6CiAgICAgICAgcV9mYWlsLnB1dF9ub3dhaXQoKHVybCwgZXhjKSkKCnFfc3VjY2VzcyA9IHF1ZXVlLlF1ZXVlKCkKcV9mYWlsID0gcXVldWUuUXVldWUoKQoKIyDQrdGC0L7RgiDQutC+0L3RgtC10LrRgdC90YvQuSDQvNC10L3QtdC00LbQtdGAINC/0L7Qt9Cy0L7Qu9GP0LXRgiDRgdC+0LfQtNCw0YLRjCDQv9GD0Lsg0YLRgNC10LTQvtCyLCDQutC+0YLQvtGA0YvQtSDQsdGD0LTRg9GCINCy0YvQv9C+0LvQvdGP0YLRjCDQt9Cw0LTQsNC90LjRjwojINCi0YDQtdC00Ysg0LHRg9C00YPRgiDRgdC+0LfQtNCw0L3RiyDQuCDQt9Cw0LLQtdGA0YjQtdC90Ysg0LrQvtGA0YDQtdC60YLQvdC+LCDQstGB0Y8g0YDQsNCx0L7RgtCwINC90LAg0LzQtdC90LXQttC00LXRgNC1CiMg0J/Rg9C7INGI0YLRg9C60LAg0L7Rh9C10L3RjCDQv9C+0LvQtdC30L3QsNGPLCDQtdGB0LvQuCDRgyDQvdCw0YEg0LHRg9C00LXRgiAxMDAgdXJsLCDQvtGH0LXQvdGMINC/0LvQvtGF0LDRjyDQuNC00LXRjyDQt9Cw0L/Rg9GB0LrQsNGC0YwgMTAwINGC0YDQtdC00L7QsiAKIyDQuCDQstGL0L/QvtC70L3Rj9GC0Ywg0LjRhSDQvtC00L3QvtCy0YDQtdC80LXQvdC90L4uCndpdGggY29uY3VycmVudC5mdXR1cmVzLlRocmVhZFBvb2xFeGVjdXRvcihtYXhfd29ya2Vycz0xMykgYXMgZXhlY3V0b3I6CiAgICBmb3IgdXJsIGluIFVSTFM6CiAgICAgICAgZXhlY3V0b3Iuc3VibWl0KGxvYWRfdXJsLCB1cmwsIDUsIHFfc3VjY2VzcywgcV9mYWlsKQoKcHJpbnQoZiJcbiBTdWNlc3NmdWxseSBsb2FkZWQ6IHtxX3N1Y2Nlc3MucXNpemUoKX0gdXJsKHMpIikKd2hpbGUgcV9zdWNjZXNzLnFzaXplKCk6CiAgICB1cmwsIGRhdGEgPSBxX3N1Y2Nlc3MuZ2V0KCkKICAgIHByaW50KGYidXJsIFt7dXJsfV0sIGNvbnRlbnQgc2l6ZToge2xlbihkYXRhKX0iKQoKcHJpbnQoZiJcbiBGYWlsZWQgdXJsczoge3FfZmFpbC5xc2l6ZSgpfSB1cmwocykiKQp3aGlsZSBxX2ZhaWwucXNpemUoKToKICAgIHVybCwgZXhjID0gcV9mYWlsLmdldCgpCiAgICBwcmludChmInVybCBbe3VybH1dLCBleGNlcHRpb246IHtleGN9IikKCg==