Как ускорить парсинг на Python?
Добрый вечер, тостерчане! Захотелось в научных целях пропарсить башорг, ithappens и задолбали. Написал банальный парсер на bs4, скорость при 4 потоках 10 постов в секунду. Сеть 100Мбит (Монреаль). Пинг до башорга 82ms. Time показывает скорость загрузки страницы в одном потоке за 365ms. При таком раскладе, только на башорг уйдет около суток. Есть ли способы ускорить процесс?
- Вопрос задан более трёх лет назад
- 2344 просмотра
Комментировать
Решения вопроса 1
Парсинг вам не нужно ускорять
Вам нужно ускорить граббинг
А ускорить его можно если сделать кеширующий днс поближе, сам граббер разместить поближе к хосту донору
И если парсинг сделать на lxml, то и ускорять там уже нечего — он и так на Си написан
Ответ написан более трёх лет назад
Комментировать
Нравится 3 Комментировать
Ответы на вопрос 3
если используете только многопоточность, то можно запускать по 20-40 потоков или больше если процессор позволяет.
увеличивайте число потоков пока не нагрузите 100Мбит или процессор
Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать
Скачайте сайты многопоточной качалкой (типа winhttrack) и парсите уже со своего диска
Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
башорг 1300+ страниц, выкачивается достаточно быстро, а дальше простой простой разбор. Также и с остальными сайтами.
Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
Ваш ответ на вопрос
Войдите, чтобы написать ответ
- Python
- +1 ещё
Почему при большом количестве строк async выдает ошибку?
- 1 подписчик
- 2 часа назад
- 19 просмотров
Многопоточный парсинг на Python
В этой статье я расскажу, как значительно ускорить парсинг сайта. Те, кто изучил парсинг и начал применять его на практике приходят к такому моменту как ожидание окончания работы парсера, в особенности, когда объем данных высок. На скорость работы влияет множество параметров, один из них — это время ответа сервера, т.к. серверу нужно время чтобы обработать информацию.
В статье я опишу один из способов борьбы с этой проблемой.
Использоваться будет библиотека «concurrent.futures». Использовать «concurrent» нужно умеренно, не стоит устраивать «DDoS» атаку на сайт.
Для создания многопотока ничего мудрёного делать не придётся, код очень прост и понятен. После установки импортируем библиотеки. Добавлены 2 дополнительные библиотеки, это «tqdm» индикатор процесса и «pandas» для создания датафрейма.
import requests import pandas as pd from tqdm import tqdm import concurrent.futures
Прописываем «headers» в request запросы, создаем сессию, объявляем функцию отправки запросов
headers = < 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36' >TIMEOUT = 10 session = requests.Session() session.headers = headers def load_url(url): answer = requests.get(url, headers=headers, timeout=TIMEOUT) return [url, answer.text]
Создаем датафрейм со списком «url» из файла «test.xlsx». Для тестирования берем только первые 2000 записей
df = pd.read_excel('test.xlsx') df.head()
Index | source.objectHrefTerm |
0 | https://test.ru/PurchaseView/43/0/0/705675 |
1 | https://test.ru/PurchaseView/30/0/0/705663 |
2 | https://test.ru/PurchaseView/43/0/0/705661 |
3 | https://test.ru/PurchaseView/30/0/0/705653 |
4 | https://test.ru/PurchaseView/20/0/0/705300 |
urls = list(df['source.objectHrefTerm'])[:2000]
Вначале протестируем время выгрузки одним потоком
out = [] for url in tqdm(urls): out.append(load_url(url))
Прогресс-бар показывает скорость выполнения — 2 минуты и 21 секунду. Среднее количество запросов в секунду — 14.15.
Теперь сделаем те же 2000 запросов, используя concurrent.futures и 2 потока. Изменяется только параметр CONNECTIONS
out = [] CONNECTIONS = 2 with concurrent.futures.ThreadPoolExecutor(max_workers=CONNECTIONS) as executor: future_to_url = (executor.submit(load_url, url) for url in urls) for future in tqdm(concurrent.futures.as_completed(future_to_url), total=len(urls)): try: data = future.result() except Exception as exc: data = str(type(exc)) finally: out.append(data)
Прогресс-бар показал скорость выполнения 1 минута и 16 секунд. В среднем 26.06 запроса в секунду.
Наблюдается уже значительное увеличение скорости. Попробуем использовать 5 потоков.
out = [] CONNECTIONS = 5
Скорость парсера увеличилась почти в 5 раз.
При использовании большего количества потоков не на все запросы приходили ответы либо на время блокировался ip адрес.
Многопоточный парсинг позволяет нам выполнять работу быстрее, в нашем случае ускорение работы достигло 4,85 раз, что дает существенную экономию времени в больших пулах запросов.
Как ускорить парсинг python
Всем привет. Я пишу бота для тг. И суть его в том, что присылаются породы кроликов и потом присылаются выбранные (например, выбрал породу минилоп, и все представители этой породы берутся с сайта). Берется картинка, порода, цена и есть ли скидка. Присылается первый кролик, потом по кнопке второй и т.д. Я заметил, что сбор данных очень долгий (1.67 сек). При нажатии на кнопку у меня заново все парсится, и поэтому все работает не очень плавно. Как можно его ускорить?
from bs4 import BeautifulSoup from datetime import timedelta, datetime from collections import namedtuple import requests import time class Parser: """ Class Parser use for parsing info about rabbits General use - take info from div tag with class 'product-wrapper' Note: Web-site: https://tsarskiykrolik.com/ Methods: -------------------- get_hours_from_td(data: datetime.timedelta) - Returns hours from timedelta convert_hours_to_word(hour: int) - Changes the ending of a word for correct form convert_days_to_word(day: int) - Changes the ending of a word for correct form parse_date(str_date: str) - Converts str date to datetime type format_datetime(date: datetime.timedelta) - Returns a string with the number of days and hours until the end of the discount parse(breed: str) - Returns a list of namedtuple with information about rabbits """ def __init__(self): pass @staticmethod def get_hours_from_td(date: timedelta) -> int: """Returns hours from timedelta""" return date.seconds // 3600 @staticmethod def convert_hours_to_word(hour: int) -> str: """Returns correct ending of a word(час/часа/часов)""" if hour str: """Returns correct ending of a word(день, дня, дней)""" if day == 1: return 'день' elif 2 datetime: """Returns date at datetime type""" return datetime.strptime(str_date, '%Y-%m-%d %H:%M:%S') def format_datetime(self, date: timedelta) -> str: """Returns a string with the number of days and hours until the end of the discount. If days until the end of discount less 0, only the hours are returned""" time_end = (date.days, self.get_hours_from_td(date)) if time_end[0] == 0 and time_end[1] > 0: # if days < 0 return f'' else: return f' и ' @staticmethod def get_url(breed: str) -> str: """Takes breed of the rabbit and returns url of them""" return f'https://tsarskiykrolik.com/product-category/kroliki/?filter_poroda=' def parse(self, breed: str) -> list[namedtuple]: """Takes breed from user(inline-button) and parse info about it from site. The Exception is raised if no discount in block""" url = self.get_url(breed) page = requests.get(url) soup = BeautifulSoup(page.text, 'html.parser') products = soup.find_all('div', class_='product-wrapper') res = [] for block in products: breed = block.find('h3').text.strip() price = block.find('span', class_='price').text.split() img_url = block.find('img').get('data-srcset').split(', ')[0][:-4] more_info = block.find('h3').find('a')['href'] end_discount = timedelta(days=0, hours=0) time_to_end = timedelta(days=0, hours=0) try: end_discount = ( self.parse_date( block.find( 'div', class_='wd-product-countdown wd-timer woodmart-product-countdown woodmart-timer').attrs[ 'data-end-date']) ) current_date = datetime.now() time_to_end = end_discount - current_date + timedelta(hours=3) except AttributeError: pass old_price = ''.join(price[:price.index('₽') + 1]) discount_price = ''.join(price[price.index('₽') + 1:]) Rabbit = namedtuple('Rabbit', 'breed, img_url, old_price, discount_price, time_to_disc_end, more_info') rabbit = Rabbit(breed, img_url, old_price, discount_price, self.format_datetime(time_to_end), more_info) res.append(rabbit) return res if __name__ == '__main__': a = Parser() start = time.monotonic() print(*a.parse('germelin'), sep='\n') print(time.monotonic() - start)
Как ускорить парсинг данных
Устали собирать и сортировать данные вручную? Эта статья познакомит вас с автоматизированными инструментами парсинга, а также готовыми к использованию наборами данных.
1 min read
Itamar Abramovich
Director of Product Managment
В этой статье мы обсудим:
- Скрейпингу и парсингу нужна крупная внутренняя инфраструктура
- Web Scraper IDE автоматизирует сбор и анализ данных с нулевой инфраструктурой
- Готовые к использованию наборы данных устраняют потребность в ручном парсинге
Скрейпингу и парсингу нужна крупная внутренняя инфраструктура
Ручной скрейпинг (скрапинг) и парсинг – утомительный процесс. Но его можно автоматизировать, если использовать бота или веб-краулера. Для тех, кто не до конца понимает суть, объясняем. Веб-скрейпинг – это метод сбора данных из интернета в базу и занесение в электронную таблицу для последующего анализа.
Парсинг используется после того, когда данные уже получены. Он помогает структурировать объемные наборы данных, чтобы люди могли их понимать, обрабатывать и конструктивно использовать информацию. Как правило, это происходит, когда преобразуют файлы HTML в текст, числовые значения или другую информацию, которую можно использовать.
Самая большая проблема в том, что веб-сайты постоянно меняют свою структуру. Из-за этого также меняются и наборы данных. Поэтому при ручном скрапинге и парсинге нужно уметь отслеживать информационные изменения, а также обеспечивать доступ к ним. Это является самой сложной частью процесса сбора данных. Для того чтобы добиться этого, необходимо задействовать много разработчиков, IT-специалистов и серверов, с которыми некоторые компании не хотят иметь дело.
Web Scraper IDE автоматизирует сбор и анализ данных с нулевой инфраструктурой
Web Scraper IDE полностью автоматизирует процесс скрапинга (скр и парсинга в режиме онлайн. Это означает, что вам не нужно создавать или поддерживать сложные системы внутри компании. Такой вариант подходит, если вы хотите передать на аутсорсинг операции по сбору данных при работе с новыми целевыми сайтами (например, компания, ориентированная на электронную коммерцию, ранее собирала данные с торговой площадки A, а теперь хочет начать собирать данные с торговой площадки B).
Преимущества инструмента в сравнении с ручным скрейпингом и парсингом:
- Получение доступа к данным, которые фильтруют, подбирают, синтезируют, обрабатывают и структурируют, чтобы вы могли сразу их использовать
- Экономия времени и ресурсов, потому что данные собирают с помощью алгоритмов, основанных на искусственном интеллекте и ML-технологиях
- Масштабирование операций по сбору данных в зависимости от вашего бюджета, изменяющихся проектов и целей
- Использование технологии, которая автоматически адаптируется к изменениям структуры целевого сайта и блокировкам
- Постоянный доступ к обновляемым и актуальным точкам доступа
Готовые к использованию наборы данных устраняют потребность в ручном парсинге
Если вы парсите популярный сайт, например:
- Маркетплейс;
- Социальную сеть;
- Сервисы туризма/гостеприимства/проката авто;
- Каталог деловых/информационных услуг.
Тогда собранные «наборы данных» (Datasets) – то, что вам нужно. Основные преимущества способа:
- Результаты появляются практически мгновенно (за нескольких минут)
- Это более экономически эффективный вариант
- Не требуются технические знания, команда DevOps в штате, инфраструктура для сбора данных
Кроме того, наше решение имеет несколько вариантов использования. Например:
- Вариант 1: Настройте нужный набор данных на основе важных параметров (например, поднабор данных, которые относятся к влиятельным лицам футбола в Испании).
- Вариант 2: Настройте набор данных на основе вашего уникального случая использования и бизнес-стратегии (например, объем определенной криптовалюты в конкретном электронном кошельке).
Подведем итоги
Bright Data предоставляет множество функций, которые соответствуют вашим текущим потребностям. Datasets обеспечивает быстрый, экономически эффективный доступ. Web Scraper IDE полностью автоматизирует сложные задачи по сбору данных и для вашего удобства предоставляет информацию членам команды, системам и алгоритмам.