Очистка тысячи URL-адресов

#python #web-scraping #beautifulsoup #python-requests

Вопрос:

У меня есть функция, которая очищает список URL-адресов, 200 тыс. URL-адресов, это заняло много времени, есть способ ускорить этот процесс?

 def get_odds(ids):  headers = {"Referer": "https://www.betexplorer.com",  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36'}  s = requests.Session()  matches=[]  for id in ids:  url = f'https://www.betexplorer.com{id}'  response = s.get(url, headers=headers)  soup = BeautifulSoup(response.text,'html.parser')  season = url.split('/')[5]   "do stuff.."  

ids — это list

 ['/soccer/england/premier-league/brentford-norwich/vyLXXRcE/' ...]  

Комментарии:

1. Первым шагом является измерение того, что занимает больше всего времени с помощью профилировщика.

2. это занимает 1-2 секунды на URL-адреса, но умноженное на 200 тысяч-это много времени..

Ответ №1:

Да, вы можете использовать многопроцессорную обработку.

Что-то вроде:

 from multiprocessing import Pool  if __name__ == "__main__":  threads = 10 # The number of concurrent requests  p = Pool(threads)  p.map(get_odds, ids)  p.terminate()  

Где идентификаторы-это список идентификаторов, а get_odds-это функция, которую вы предоставили, но изменили для работы ТОЛЬКО с ОДНИМ из идентификаторов. Имейте в виду, что вы будете отправлять на их сервер 10 запросов одновременно, и это может привести к временной блокировке ip-адресов (поскольку вас считают враждебным). Вы должны помнить об этом и настроить размер пула и / или добавить логику сна ().

Функция получения коэффициентов должна быть такой:

 def get_odds(id):  headers = {"Referer": "https://www.betexplorer.com",  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36'}  s = requests.Session()  matches=[]  url = f'https://www.betexplorer.com{id}'  response = s.get(url, headers=headers)  soup = BeautifulSoup(response.text,'html.parser')  season = url.split('/')[5]   "do stuff.."  

Комментарии:

1. Хм, похоже, проблема связана с вводом-выводом, так что вам лучше использовать threading или asyncio ?

2. похоже, что ничего не получается у меня получилось season = url.split('/')[5] IndexError: list index out of range

3. Многопроцессорная обработка @Timus занимает больше места в памяти, чем потоковая обработка, но, по моему опыту, приводит к гораздо более удобочитаемому коду и, следовательно, к меньшему количеству ошибок, чем потоковая обработка. Что касается очистки веб-страниц, я обнаружил, что вы сталкиваетесь с ограничениями скорости намного раньше, чем с проблемами с памятью. У меня нет опыта работы с asyncio, и поэтому я не могу комментировать.

4. @luka Это проблема с вашей функцией get_odds, а не с кодом, который я предоставил. После того, как ваш идентификатор будет отформатирован в URL-адрес, в нем будет меньше 6 косых черт, поэтому вы получите ошибку индекса. Можете ли вы поделиться тем, как выглядят ваши удостоверения личности?

5. @PeterWhite ‘/футбол/англия/премьер-лига/брентфорд-норвич/vyLXXRcE/’ это то, что выглядит как список идентификаторов идентификаторов. Когда я запускаю скрипт без многопоточности, у меня нет ошибок.

Ответ №2:

Вы можете позволить им работать параллельно с помощью многопоточности. Например, создать 10 потоков и на основе окончания вашего идентификатора (0, 1, 2, 3, …) знает поток, какой идентификатор он должен очистить. Работает только при достаточной вычислительной мощности и стабильном подключении к Интернету.

ИЗМЕНИТЬ: Поскольку идентификатор-это список, вместо этого проверьте индекс, чтобы определить, какой поток должен очистить какой веб-сайт.