Ускорение алгоритма скрипта python
Подскажите как можно ускорить выполнение скрипта на python
from bs4 import BeautifulSoup as Soup
import requests
import calendar
import time
def parse(link):
response = requests.get(link)
if response.status_code == 200:
soup = Soup(response.content, 'html.parser')
all_station = soup.find("ul", {"class":"big-blue-billet__list"})
all_link_station = [[link['href'],link.getText()] for link in all_station.select("a")]
return all_link_station
def main(params):
station_static = {}
for link in parse('http://www.pogodaiklimat.ru/archive.php?id=by'):
response = requests.get(f'http://www.pogodaiklimat.ru/{link[0]}',params=params)
statics_dict = {}
if response.status_code == 200:
soup = Soup(response.content, 'html.parser')
date_time = ['-'.join(dt.getText().split()) for dt in soup.select(".archive-table-left-column table tr" )[1:]]
temperature = [t.find_all('td')[5].getText() for t in soup.select(".archive-table-wrap table tr")[1:]]
for el in range(len(date_time)):
statics_dict[date_time[el]]=temperature[el]
station_static[link[1]] = statics_dict
return station_static
if __name__ == '__main__':
start_time = time.time()
params = {
'bday':1, #первый день месяца
'fday':28, #последний день
'amonth':2, #номер месяца январь-1 декабрь-12
'ayear':2011, #год
'bot':2, #защита от ботов
}
main(params)
print("--- %s seconds ---" % (time.time() - start_time))
сейчас время выполнения 46 секунд. Думаю как-то можно распараллелить функцию main , конкретно цикл
for link in parse('http://www.pogodaiklimat.ru/archive.php?id=by'):
и в разных потоках получить данные с разных ссылок. Но мало в этом опыта и не знаю в какую сторону смотреть. Подскажите как поступать в таких случаях.
Ответы (1 шт):
Автор решения: splash58
→ Ссылка
В нынешней реализации библиотека multiprocessing позволяет весьма просто и удобно распараллеливать вычисления:
# Добавим в импорт
import multiprocessing as mp
# сделаем функцию из тела цикла
def fun1(args):
link, params = args
response = requests.get(f'http://www.pogodaiklimat.ru/{link[0]}', params=params)
statics_dict = {}
if response.status_code == 200:
soup = Soup(response.content, 'html.parser')
date_time = ['-'.join(dt.getText().split()) for dt in soup.select(".archive-table-left-column table tr")[1:]]
temperature = [t.find_all('td')[5].getText() for t in soup.select(".archive-table-wrap table tr")[1:]]
for el in range(len(date_time)):
statics_dict[date_time[el]] = temperature[el]
#station_static[link[1]] = statics_dict
return (link[1], statics_dict)
def main(params):
station_static = {}
# создаем пул
pool = mp.Pool(mp.cpu_count())
# собираем список аргументов функции
links = parse('http://www.pogodaiklimat.ru/archive.php?id=by')
# вперед
lst = pool.map(fun1, zip(links, [params]*len(links)))
return lst
if __name__ == '__main__':
start_time = time.time()
params = {
'bday':1, #первый день месяца
'fday':28, #последний день
'amonth':2, #номер месяца январь-1 декабрь-12
'ayear':2011, #год
'bot':2, #защита от ботов
}
print(dict(main(params)))
print("--- %s seconds ---" % (time.time() - start_time))
Примерно в 7-8 раз быстрее