Можно ли еще больше ускорить код? Использую async
В файле asyncio_IMDB_scraping.py записаны ассинхронные функции, которые собирают данные о фильмах с IMDB (страна, язык, режиссер, актерский состав)
ID фильмов хранятся в data.xlsx и вынимаются от туда с помощью файла scrap_db.py. Я что-то пока не придумал способа лучше. Когда я импортировал данные из exel в DataFrame в asyncio_IMDB_scraping.py, ассинхронные функции отказывались работать. А со списком все работает.
Код, который записывает полученные данные в новый exel файл я даже не дописывал, потому что, по моим подсчетам данная программа будет собирать инфу 9 часов. Плюс есть подозрение, что Error 503 не даст это сделать в любом случае (когда я спарсил 50 страниц, какое-то время при заходе на сайт мне высвечивалась такая ошибка)
Запрос: Я только учусь, это мой 2й парсинг, прошу подсказать как можно исправить данный код, рад буду любым рекомендациям! Самая главная рекомендация, которую хочу получить - как ускорить работу по сбору такого объема информации? 9 часов это нереально много…
Код из основного файла:
import asyncio
import aiohttp
from bs4 import BeautifulSoup
import pandas as pd
from unidecode import unidecode
import re
import time
from scrap_db import movie_id_list
start_time = time.time()
async def get_country_language(session, movie_id):
url = 'https://www.imdb.com/title/' + movie_id
async with session.get(url) as resp:
assert resp.status == 200
print(f'get url: {url}')
resp_text = await resp.text()
soup = BeautifulSoup(resp_text, 'lxml')
origin = soup.find_all('li', attrs = {'data-testid': 'title-details-origin'})
for link in origin:
country = link.find('a').get_text()
lang = soup.find_all('li', attrs = {'data-testid': 'title-details-languages'})
for link in lang:
language = link.find('a').get_text()
countries.append(country)
languages.append(language)
async def get_director_cast(session, movie_id):
url_cast = f'https://www.imdb.com/title/{movie_id}/fullcredits/'
async with session.get(url_cast) as resp:
assert resp.status == 200
print(f'get url: {url_cast}')
resp_text = await resp.text()
soup = BeautifulSoup(resp_text, 'lxml')
try:
tables = soup.find_all('table', attrs={'class': 'simpleTable simpleCreditsTable'})
table_all = []
for table in tables:
table_all.append(table.find('a').get_text())
director = table_all[0]
except:
director = ' '
cast_data = soup.find('table', 'cast_list')
cast = ''
try:
for tables in cast_data.find_all('td'):
if tables.has_attr('class'):
continue
else:
for links in tables.find_all('a'):
if links.has_attr('class'):
continue
else:
cast += links.get_text() + ', '
except:
cast = ' '
directors.append(re.sub("^\s+|\n|\r|\s+$", '', director))
casts.append(re.sub("^\s+|\n|\r|\s+$", '', cast[:-2]))
countries = []
languages = []
directors = []
casts = []
async def load_country_language():
async with aiohttp.ClientSession() as session:
tasks = []
for i in range(0, 10):
task = asyncio.create_task(get_country_language(session, movie_id=movie_id_list[i]))
tasks.append(task)
await asyncio.gather(*tasks)
async def load_director_cast():
async with aiohttp.ClientSession() as session:
tasks = []
for i in range(0, 10):
task = asyncio.create_task(get_director_cast(session, movie_id=movie_id_list[i]))
tasks.append(task)
await asyncio.gather(*tasks)
asyncio.run(load_country_language())
asyncio.run(load_director_cast())
end_time = time.time() - start_time
print(countries)
print(languages)
print(directors)
print(casts)
print(f'Elapsed time: {end_time}')