перейти к содержанию

Вот сообщение в блоге объемом более 2000 слов на тему «Как очистить поиск Algolia»:

Введение

Algolia — это популярный поисковый API, который обеспечивает функции поиска на многих веб-сайтах в Интернете. Это позволяет веб-сайтам осуществлять быстрый и релевантный поиск без необходимости запуска сложной поисковой инфраструктуры.

Некоторые примеры популярных веб-сайтов, использующих Algolia, включают:

  • Reddit.
  • Medium
  • GitHub
  • StackOverflow
  • HackerNews

Цель этого поста — объяснить:

  1. Что такое Алголия и как она работает
  2. Как очистить результаты поиска Algolia с помощью Python
  3. Методы эффективного парсинга Алголии в больших масштабах
  4. Как избежать блокировки при парсинге Algolia

К концу вы поймете, как создать масштабируемый парсер Algolia для любого веб-сайта, использующего его.

Что такое Алголия?

Algolia — это размещенный API поиска, который предоставляет такие услуги, как индексирование, поиск и рекомендации. Его часто называют поставщиком поиска как услуги (SaaS).

Ключевые ценностные предложения Algolia включают в себя:

  • Быстрый поиск – Algolia утверждает, что может выполнять поиск по миллиардам записей менее чем за 100 мс. Это на порядки быстрее, чем поиск по собственной инфраструктуре.

  • Соответствующий поиск – Algolia обрабатывает такие вещи, как толерантность к опечаткам, синонимы и обучение на основе поведения пользователей, чтобы возвращать наиболее релевантные результаты.

  • Хостинг-сервис – Algolia заботится о таких вещах, как масштабирование и избыточность. У вас нет инфраструктуры, которой вы могли бы управлять.

  • Доступ к API – Доступ к функциям поиска можно получить через API, что позволяет легко интегрировать их в веб-сайты, мобильные приложения и т. д.

Algolia предоставляет клиентские библиотеки для большинства основных языков и фреймворков, которые поддерживают связь через API. Во внешнем интерфейсе разработчики добавляют код JavaScript для взаимодействия с API Algolia.

Итак, Algolia обеспечивает размещенный и масштабируемый поиск через API. Это позволяет веб-сайтам быстро создавать отличный поиск без необходимости самостоятельно создавать сложные системы.

Очистка поиска Algolia с помощью Python

Теперь, когда мы понимаем, что такое Algolia, давайте посмотрим, как мы можем очистить результаты поиска Algolia с помощью Python.

Парсинг Algolia прост, поскольку API общедоступен и документирован. Нам просто нужно:

  1. Определите конечную точку и параметры API
  2. Извлеките все ключи доступа
  3. Отправляйте поисковые запросы и анализируйте ответ JSON.

Давайте рассмотрим полный пример парсинга веб-сайта на базе Algolia.

Поиск конечной точки API

Во-первых, нам нужно найти конечную точку API, используемую веб-сайтом для поиска. Самый простой способ — открыть сайт в браузере, запустить поисковый запрос и проверить сетевые запросы в инструментах разработчика.

Например, на HackerNews мы видим запрос, сделанный на:

https://hn.algolia.com/api/v1/search?query=python

Ассоциация /api/v1/search path выдает, что это API поиска Algolia. Мы также видим поисковый запрос python передается как параметр запроса.

Проверив ответ, мы видим, что он возвращает JSON с результатами. Теперь мы знаем конечную точку API и параметр поиска, который нужно использовать.

Получение ключей API

Далее нам нужно получить ключ API, необходимый для аутентификации. Снова проверив сетевой запрос, мы видим, что он прошел через X-Algolia-API-Key заголовка.

Мы можем извлечь этот ключ API и добавить его в наши запросы. Может потребоваться дополнительный обратный инжиниринг, если ключ запутан в JavaScript.

Создание поисковых запросов

Имея конечную точку и ключ API, мы теперь можем выполнять поисковые запросы в Python:

import requests 

api_key = "abc123" # Extracted key 

search_url = "https://hn.algolia.com/api/v1/search"

params = {
  ‘query‘: ‘python‘,
  ‘hitsPerPage‘: 100, 
  ‘attributesToSnippet‘: [‘title:10‘]
}

headers = {
  "X-Algolia-API-Key": api_key
}

response = requests.get(search_url, params=params, headers=headers)
data = response.json()

print(data[‘hits‘])

Мы делаем запрос GET к конечной точке API, передавая наш поисковый запрос, количество обращений на страницу и заголовок ключа API. Результат содержит результаты поиска в формате JSON, которые мы можем анализировать и обрабатывать по мере необходимости.

И теперь у нас есть базовый скребок Algolia!

Парсинг дополнительных страниц

Одним из ограничений является то, что API возвращает только первую страницу результатов. Чтобы получить дополнительные страницы, нам нужно передать page увеличение параметра от 0:

# First page
params[‘page‘] = 0 

# Second page
params[‘page‘] = 1 

# Third page
params[‘page‘] = 2

Чтобы очистить все страницы, мы можем выполнять циклические запросы, увеличивая номер страницы до тех пор, пока результаты не перестанут возвращаться.

Собираем это вместе:

from typing import Iterator

def scrape_search(search_term: str) -> Iterator[dict]:

  params = {
    ‘query‘: search_term,
    ‘hitsPerPage‘: 100,
  }

  page = 0
  while True:
    params[‘page‘] = page
    resp = requests.get(search_url, params=params, headers=headers)
    data = resp.json()

    if not data[‘hits‘]:
      break

    yield from data[‘hits‘]

    page += 1

Это перебирает страницы и дает все результаты.

Чтобы собрать все результаты:

results = []

for result in scrape_search("python"):
  results.append(result)

print(len(results))

И теперь у нас есть полноценный пагинатор для сбора всех результатов поиска в Алголии!

Очистка Алголии в масштабе

Базовый парсер, описанный выше, работает, но не оптимизирован для крупномасштабного парсинга. Проблемы, с которыми вы можете столкнуться:

  • Замедлять – Синхронные запросы замедляют очистку сотен страниц.
  • Хрупкая – Один сбой ломает весь процесс очистки.
  • запрещенный – Парсинг с одного IP рискует быть заблокированным.

Давайте посмотрим, как решить эти проблемы для надежного крупномасштабного парсинга.

Асинхронные запросы

Чтобы ускорить парсинг, мы можем использовать асинхронные запросы. Это позволяет нам одновременно обрабатывать множество запросов.

Например, с asyncio модуль:

import asyncio

async def fetch_page(page):
  params[‘page‘] = page
  resp = await asyncio.to_thread(requests.get, search_url, params=params) 
  return resp.json()

async def async_scrape():
  page = 0 
  while True:
    tasks = [asyncio.create_task(fetch_page(page + i)) for i in range(10)]
    results = await asyncio.gather(*tasks)

    for data in results:
      if not data[‘hits‘]:
        return

      for hit in data[‘hits‘]:
        yield hit

    page += 10

pages = async_scrape()  

При этом на каждой итерации одновременно извлекается 10 страниц. При асинхронных запросах парсер работает на порядок быстрее.

Повторные попытки и отказоустойчивость

Сетевые запросы склонны к периодическим сбоям. Мы можем добавить повторы для корректной обработки ошибок:

from time import sleep

async def fetch_page(page):

  for retry in range(3):

    try:
      return await asyncio.to_thread(requests.get, search_url, params=params) 
    except Exception as e:
      print(f"Error: {e}, retrying")
      sleep(1)

  print(f"Failed to fetch page {page} after {retries} retries")
  return {‘hits‘: []} # Return empty result

Это просто повторяет до 3 раз в случае любой неудачи. Также могут быть добавлены другие улучшения, такие как экспоненциальная задержка.

Для большей устойчивости мы можем обернуть весь цикл очистки в попытку/исключение и повторить попытку в случае непредвиденных сбоев.

Благодаря повторным попыткам на нескольких уровнях парсер может восстановиться после различных ошибок и продолжить работу.

Вращающиеся прокси

Удаление слишком большого количества данных с одного IP-адреса может привести к блокировке. Чтобы предотвратить это, мы можем маршрутизировать запросы через разные прокси, используя такие модули, как requests-proxy-killer:

from proxy_killer import KillerScraper

scraper = KillerScraper(use_cache=False, max_retries=3)

async def fetch_page(page):

  for retry in range(3): 
    try:
      proxy = scraper.get_proxy() # Rotate proxy
      resp = scraper.get(search_url, proxies=proxy, params=params)
      return resp.json()
    except Exception as e:
      print(f"Error: {e}, retrying")
      sleep(1)

# Remainder same as above

Направляя каждый запрос через другой IP-адрес прокси, мы можем выполнять масштабный анализ, не беспокоясь о блоках.

Вышеописанные шаги позволяют нам создать надежный, высокопроизводительный и крупномасштабный парсер Algolia на Python. Те же принципы применимы к любому языку.

Как избежать блоков при очистке Algolia

Последняя проблема, которую необходимо решить, — это избежать блокировок со стороны самого сервиса Algolia. Если вы делаете слишком много агрессивных запросов, Algolia может заблокировать ваш IP-адрес или ограничить запросы.

Вот несколько советов, как вежливо парсить и минимизировать блоки:

  • Предельная ставка: не перегружайте API сотнями одновременных запросов. Начните с малого и постепенно увеличивайте.

  • Используйте прокси: чередуйте разные IP-адреса, чтобы распределить нагрузку и избежать концентрированных запросов.

  • Рандомизировать пользовательские агенты: меняйте заголовок пользовательского агента между запросами.

  • Следуйте файлу robots.txt: убедитесь, что ваш парсер подчиняется правилам robots.txt.

  • Использовать логику повтора: Экспоненциальная отсрочка, если скорость ограничена или заблокирована.

  • Скрапинг в периоды низкой посещаемости: ориентируйтесь на будние ночи, когда нагрузка ниже.

  • Внимательно следить: проверьте, нет ли возрастающих сбоев или регулирования.

При правильном уходе вы можете построить надежные и долговечные скреперы Algolia. Но не забывайте внимательно отслеживать и со временем адаптировать свой подход.

Парсинг вспомогательных библиотек

Ручное управление всеми сложностями масштабирования и устойчивости может оказаться обременительным. Существуют различные коммерческие инструменты для упрощения парсинга веб-страниц.

Например:

Эти инструменты упрощают создание надежных парсеров без необходимости самостоятельно писать сложную логику. Смотрите мое руководство по как и когда использовать API парсинга.

Подводя итог

Вот ключевые выводы:

  • Algolia предоставляет хостинговый поиск через API для легкой интеграции с сайтами.
  • API поиска является общедоступным, и его можно очистить, извлекая конечную точку и ключи.
  • Масштабный парсинг требует асинхронных запросов и ротации прокси.
  • Внимательно следите и вежливо очищайте, чтобы избежать блоков.
  • Коммерческие услуги по очистке могут упростить большие работы по очистке.

Я надеюсь, что этот пост предоставит хороший обзор того, как эффективно очищать поисковый API Algolia в масштабе с помощью Python. Те же принципы применимы и к другим языкам.

Дайте мне знать, если у вас есть еще вопросы!

Теги:

Присоединяйтесь к беседе

Ваш электронный адрес не будет опубликован. Обязательные поля помечены * *