Как ускорить цикл BeautifulSoup for loop
У меня есть цикл for, который анализирует 6 урлов, чтобы получить текст первого класса с "GARawf". Цикл работает, однако я заметил, что теперь загрузка страницы занимает около 9 секунд по сравнению с 1 секундой раньше. Поскольку я новичок в Django и BeautifulSoup, мне интересно, есть ли способ рефакторинга кода, чтобы он загружал представление быстрее.
views.py
# create list of cities
city_list = ["Toronto", "Montreal", "Calgary", "Edmonton", "Vancouver", "Quebec"]
# create price list
prices_list = []
# set origin for flight
origin = "Madrid"
#origin_urllib = urllib.parse.quote_plus(origin)
# set headers
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36"
}
for i in city_list:
# set destination for flight
destination = i
# set search query
url = "https://google.com/search?q=" + origin + " to " + destination + " Google Flights"
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'lxml')
# get price element
prices = soup.find("span", attrs={"class": "GARawf"})
if prices != None:
prices_list.append(prices.text.strip())
else:
prices_list.append("Not Available")
Я бы использовал потоки для вызова функции, выполняющей запросы, чтобы запросы выполнялись одновременно. Вы захотите import concurrent.futures
Затем переместите список citylist в функцию threading, как показано ниже. Подробнее об использовании пулов потоков
def get_prices(city):
prices_list = []
origin = "Madrid"
#origin_urllib = urllib.parse.quote_plus(origin)
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119
Safari/537.36"
}
url = "https://google.com/search?q=" + origin + " to " + destination + " Google Flights"
with requests.get(url, headers=headers) as response:
soup = BeautifulSoup(response.text, 'lxml')
# get price element
prices = soup.find("span", attrs={"class": "GARawf"})
if prices != None:
prices_list.append(prices.text.strip())
else:
prices_list.append("Not Available")
return prices_list
def run_threadPool():
with concurrent.futures.ThreadPoolExecutor() as executor:
city_list = ["Toronto", "Montreal", "Calgary", "Edmonton", "Vancouver", "Quebec"]
results = executor.map(get_prices, city_list)
for result in results:
#do what you need here....
t2 = time.perf_counter()
print(f'Finished in {t2-t1} seconds')