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}")

