Я хочу проверить ссылки на более чем 10 тыс. Страниц за один прогон. У меня есть рабочее решение, но, к сожалению, оно СЛИШКОМ слишком медленное, потому что оно обрабатывает requests.get
один за другим, поэтому программе всегда нужно ждать ответа от URL, прежде чем обрабатывать следующий URL.
У меня есть пытался найти решение и заметил эту статью с основами многопоточности, асинхронных запросов и многопроцессорности. Попытался реализовать асинхронное решение для моего случая и придумал следующий тестовый код:
import asyncio
import aiohttp
import time
from bs4 import BeautifulSoup
DOMAIN = 'forbes.com'
class Link:
url = None
anchor = None
rel = None
async def get_link(session, url):
internal_links = list()
async with session.get(url) as response:
soup = BeautifulSoup(response.content, 'html.parser', from_encoding='iso-8859-1')
for link in soup.find_all('a'):
if DOMAIN in link.get('href'):
internal_links.append(Link())
internal_links[-1].url = link.get('href')
internal_links[-1].anchor = link.text
internal_links[-1].rel = link.get('rel')
if len(internal_links) != 0:
for internal_link in internal_links:
print(f'URL is {internal_link.url}\n Anchor is {internal_link.anchor}\n Rel is {internal_link.rel}\n\n')
async def get_all_links(urls):
async with aiohttp.ClientSession() as session:
tasks = list()
for url in urls:
task = asyncio.ensure_future(get_link(session, url))
tasks.append(task)
await asyncio.gather(*tasks, return_exceptions=True)
if __name__ == '__main__':
pages = [
'https://www.forbes.com/',
'https://www.forbes.com/sites/davidphelan/2020/02/13/apple-reveals-dazzlingly-different-apple-watch-design--features/',
'https://www.forbes.com/sites/johnarcher/2020/02/12/netflix-and-samsung-reveal-controversial-exclusive-content-deal/',
'https://www.forbes.com/sites/jamiecartereurope/2020/02/12/voyager-1s-iconic-pale-blue-dot-photo-is-30-years-old-so-nasa-made-a-new-one/',
'https://www.forbes.com/sites/daveywinder/2020/02/13/love-is-not-getting-catfished-creeped-or-scammed-this-valentines-day/',
'https://www.forbes.com/sites/daveywinder/2020/02/12/cia-secretly-bought-global-encryption-provider-built-backdoors-spied-on-100-foreign-governments/',
'https://www.forbes.com/sites/kateoflahertyuk/2020/02/12/apple-just-made-a-striking-new-security-move-that-could-impact-all-users/',
'https://www.forbes.com/sites/csylt/2020/02/12/london-to-get-worlds-first-batman-themed-restaurant/',
'https://www.forbes.com/sites/davidnikel/2020/02/13/is-anything-truly-scandinavian-the-bizarre-sas-ad-controversy-explained/',
'https://www.forbes.com/sites/ceciliarodriguez/2020/02/13/wildlife-photographer-of-the-year-peoples-choice-winning-images-released/',
'https://www.forbes.com/sites/davidphelan/2020/02/12/apple-to-launch-surprise-new-airpods-pro-in-months-report-says/',
'https://www.forbes.com/sites/davidphelan/2020/02/11/why-apple-ios-1331-matters-iphone-u1-tracking-fix-screen-time/'
] * 50
start_time = time.time()
asyncio.get_event_loop().run_until_complete(get_all_links(pages))
duration = time.time() - start_time
print(f'Downloaded {len(pages)} pages in {duration} seconds!')
Сразу же я столкнулся с несколькими проблемами:
print
делает не работает с get_link, поэтому у меня нет возможности проверить, действительно ли он работает так, как нужно, или нет.
Я не могу понять, как вернуть данные из get_link
и get_all_links
к моей основной программе. В этом конкретном случае c как мне получить все данные из internal_links
в get_link
, чтобы я мог продолжить их обработку в main
?
Я не могу понять, как правильно используйте прокси и заголовки, когда дело доходит до асинхронного решения. Это было легко с пошаговым решением. Я мог бы просто использовать proxyscrape
и получить рабочий прокси для каждой requests.get
строки. Здесь я не уверен, как реализовать прокси и user-agent.
Я не могу понять, как правильно написать try-исключение, кроме как в этом случае и как получить ошибки процесса, указанные c такие как TooManyRedirects
, ProxyError
, et c.
Я не могу понять, что именно означают async with
и async def
. Мол, это очевидно на более высоком уровне, но что на самом деле происходит, когда мы пишем async
до def
и with
?
Не могли бы вы, ребята, пожалуйста, помогите мне с вопросами выше