Skip to main content

Professional Python client for XMLRiver API with full coverage

Project description

XMLRiver Pro

Python Version License Coverage

Fork of KursHub-ru/xmlriver

Python библиотека для работы с API xmlriver.com. Расширенная версия с поддержкой всех типов поиска.

Поддерживает все типы поиска в Google и Yandex: органический поиск, новости, изображения, карты, реклама и специальные блоки.

✨ Что умеет

  • 🔍 Органический поиск в Google и Yandex
  • 📰 Поиск по новостям с фильтрами времени
  • 🖼️ Поиск по изображениям (размер, цвет, тип)
  • 🗺️ Поиск по картам с координатами
  • 📢 Рекламные блоки (верхние и нижние)
  • 🧩 Специальные блоки (OneBox, Knowledge Graph)
  • Асинхронная поддержка с aiohttp
  • 🔄 Параллельные запросы с asyncio

🏗️ Особенности

  • ✅ Полная типизация для Python 3.10+
  • 🏛️ Модульная архитектура
  • 🧪 66 тестов с покрытием 57%
  • ⚠️ Специализированные исключения
  • ✔️ Валидация параметров
  • Синхронные и асинхронные клиенты
  • 🔄 Поддержка многопоточности и параллелизма

📦 Установка

📦 Из PyPI (рекомендуется):

# Установка последней версии
pip install xmlriver-pro

# Установка конкретной версии
pip install xmlriver-pro==1.1.1

# Обновление до последней версии
pip install --upgrade xmlriver-pro

🚀 Из GitHub:

# Установка последней версии
pip install git+https://github.com/Eapwrk/xmlriver-pro.git

# Установка конкретной версии
pip install git+https://github.com/Eapwrk/xmlriver-pro.git@v1.1.1

# Обновление до последней версии
pip install --upgrade git+https://github.com/Eapwrk/xmlriver-pro.git

🔍 Проверка версии:

python -c "import xmlriver_pro; print(xmlriver_pro.__version__)"

🔄 Обновления

📋 Как узнать об обновлениях:

📚 История изменений:

  • 📄 CHANGELOG.md - полная история изменений
  • 🏷️ GitHub Releases - релизы с описанием
  • 🔄 Semantic Versioning - мажорные.минорные.патч версии

🚀 Как обновляться:

# Проверить текущую версию
pip show xmlriver-pro

# Обновить до последней версии
pip install --upgrade xmlriver-pro

# Обновить до конкретной версии
pip install xmlriver-pro==1.1.0

Для разработки:

git clone https://github.com/Eapwrk/xmlriver-pro.git
cd xmlriver-pro
pip install -e .

🔧 Зависимости

Основные:

  • requests - HTTP запросы к API
  • xmltodict - парсинг XML ответов
  • aiohttp - асинхронные HTTP запросы

Для разработки:

  • pytest - тестирование
  • black - форматирование кода
  • pylint - анализ кода
  • mypy - проверка типов

⚙️ Конфигурация

Все клиенты поддерживают настройку retry механизма и таймаутов:

Параметры конфигурации:

Параметр Тип По умолчанию Описание
timeout int 60 Таймаут запроса в секундах (максимум 60)
max_retries int 3 Максимальное количество попыток повтора
retry_delay float 1.0 Базовая задержка между попытками в секундах
enable_retry bool True Включить автоматические повторы

Экспоненциальный backoff:

При включенном retry используется экспоненциальная задержка:

  • 1-я попытка: retry_delay * 1 = 1.0 сек
  • 2-я попытка: retry_delay * 2 = 2.0 сек
  • 3-я попытка: retry_delay * 4 = 4.0 сек
  • 4-я попытка: retry_delay * 8 = 8.0 сек

Примеры конфигурации:

# Стандартная конфигурация (рекомендуется)
client = GoogleClient(user_id=123, api_key="key")

# Кастомные настройки retry
client = GoogleClient(
    user_id=123, 
    api_key="key",
    timeout=120,        # 2 минуты
    max_retries=5,      # 5 попыток
    retry_delay=2.0     # базовая задержка 2 сек
)

# Отключить retry для продвинутых пользователей
client = GoogleClient(
    user_id=123, 
    api_key="key",
    enable_retry=False  # без повторов
)

# Асинхронный клиент с настройками
async with AsyncGoogleClient(
    user_id=123,
    api_key="key", 
    max_retries=3,
    retry_delay=1.5
) as client:
    result = await client.search("python")

🚀 Быстрый старт

from xmlriver_pro import GoogleClient, YandexClient

# Инициализация клиентов
google = GoogleClient(user_id=123, api_key="your_google_key")
yandex = YandexClient(user_id=123, api_key="your_yandex_key")

# Органический поиск
google_results = google.search("python programming")
yandex_results = yandex.search("программирование на python")

# Результаты поиска
google_count = google_results.total_results
yandex_count = yandex_results.total_results

⚡ Асинхронное использование

Базовый асинхронный поиск

import asyncio
from xmlriver_pro import AsyncGoogleClient, AsyncYandexClient

async def main():
    # Google поиск
    async with AsyncGoogleClient(user_id=123, api_key="your_google_key") as google:
        results = await google.search("python programming")
        print(f"Google: {results.total_results} результатов")
    
    # Yandex поиск
    async with AsyncYandexClient(user_id=123, api_key="your_yandex_key") as yandex:
        results = await yandex.search("программирование на python")
        print(f"Yandex: {results.total_results} результатов")

# Запуск
asyncio.run(main())

Параллельные запросы

import asyncio
from xmlriver_pro import AsyncGoogleClient

async def parallel_search():
    async with AsyncGoogleClient(user_id=123, api_key="your_key") as google:
        # Создаем задачи для параллельного выполнения
        tasks = [
            google.search("python programming"),
            google.search("machine learning"),
            google.search("data science")
        ]
        
        # Выполняем все задачи параллельно
        results = await asyncio.gather(*tasks)
        
        for i, result in enumerate(results):
            print(f"Запрос {i+1}: {result.total_results} результатов")

asyncio.run(parallel_search())

Смешанный поиск Google + Yandex

import asyncio
from xmlriver_pro import AsyncGoogleClient, AsyncYandexClient

async def mixed_search():
    query = "программирование на python"
    
    async with AsyncGoogleClient(user_id=123, api_key="google_key") as google, \
             AsyncYandexClient(user_id=123, api_key="yandex_key") as yandex:
        
        # Поиск в обеих системах параллельно
        google_task = google.search(query)
        yandex_task = yandex.search(query)
        
        google_results, yandex_results = await asyncio.gather(
            google_task, yandex_task
        )
        
        print(f"Google: {google_results.total_results} результатов")
        print(f"Yandex: {yandex_results.total_results} результатов")

asyncio.run(mixed_search())

📰 Поиск по новостям

from xmlriver_pro import GoogleNews, YandexNews
from xmlriver_pro.core.types import TimeFilter

google_news = GoogleNews(user_id=123, api_key="your_key")
news_results = google_news.search_news("python", time_filter=TimeFilter.LAST_WEEK)

yandex_news = YandexNews(user_id=123, api_key="your_key")
yandex_news_results = yandex_news.search_news_last_day("python новости")

🖼️ Поиск по изображениям

from xmlriver_pro import GoogleImages

images = GoogleImages(user_id=123, api_key="your_key")

image_results = images.search_images("python logo", count=20)
large_images = images.search_images_by_size("python logo", "large")
color_images = images.search_images_by_color("python logo", "blue")

🗺️ Поиск по картам

from xmlriver_pro import GoogleMaps

maps = GoogleMaps(user_id=123, api_key="your_key")

map_results = maps.search_maps(
    query="кафе Москва",
    zoom=12,
    coords=(55.7558, 37.6176)
)

nearby_cafes = maps.search_nearby("кафе", coords=(55.7558, 37.6176), radius=1000)

📢 Рекламные блоки

from xmlriver_pro import GoogleAds, YandexAds

google_ads = GoogleAds(user_id=123, api_key="your_key")
ads_response = google_ads.get_ads("python programming")

yandex_ads = YandexAds(user_id=123, api_key="your_key")
yandex_ads_response = yandex_ads.get_ads("программирование python")

🧩 Специальные блоки

from xmlriver_pro import GoogleSpecialBlocks, YandexSpecialBlocks

# Google специальные блоки
google_special = GoogleSpecialBlocks(user_id=123, api_key="your_key")

# OneBox документы
onebox_docs = google_special.get_onebox_documents("python", ["organic", "video"])

# Knowledge Graph
kg = google_special.get_knowledge_graph("Python programming language")

# Калькулятор
calc_result = google_special.get_calculator("2 + 2")

# Yandex колдунщики
yandex_special = YandexSpecialBlocks(user_id=123, api_key="your_key")

# Погода
weather = yandex_special.get_weather("погода Москва")

# Переводчик
translation = yandex_special.get_translator("hello world")

🔧 Расширенные возможности

✔️ Валидация параметров

from xmlriver_pro.utils import validate_coords, validate_zoom, validate_url

# Валидация координат
coords = (55.7558, 37.6176)
if validate_coords(coords):
    # Координаты валидны

# Валидация zoom
if validate_zoom(12):
    # Zoom валиден

# Валидация URL
if validate_url("https://python.org"):
    # URL валиден

📝 Форматирование результатов

from xmlriver_pro.utils import format_search_response, format_ads_response

# Форматирование результатов поиска
formatted_results = format_search_response(search_results)

# Форматирование рекламных блоков
formatted_ads = format_ads_response(ads_response)

⚠️ Обработка ошибок

from xmlriver_pro.core import (
    XMLRiverError, AuthenticationError, RateLimitError, 
    NoResultsError, NetworkError, ValidationError,
    InsufficientFundsError, ServiceUnavailableError
)

try:
    results = google.search("python")
except AuthenticationError as e:
    # Ошибка аутентификации (коды 31, 42, 45)
    logger.error(f"Authentication failed: {e}")
except RateLimitError as e:
    # Превышен лимит запросов (коды 110, 111, 115)
    logger.warning(f"Rate limit exceeded: {e}")
except NoResultsError as e:
    # Нет результатов поиска (код 15)
    logger.info(f"No results found: {e}")
except InsufficientFundsError as e:
    # Недостаточно средств (код 200)
    logger.error(f"Insufficient funds: {e}")
except ServiceUnavailableError as e:
    # Сервис недоступен (коды 101, 201)
    logger.warning(f"Service unavailable: {e}")
except NetworkError as e:
    # Ошибка сети (коды 500, 202) - требует повтора
    logger.error(f"Network error: {e}")
except ValidationError as e:
    # Ошибка валидации параметров (коды 2, 102-108, 120, 121)
    logger.error(f"Validation error: {e}")

📊 Статистика и мониторинг

# Получение баланса (один на весь аккаунт)
balance = google.get_balance()  # или yandex.get_balance() - результат одинаковый

# Получение стоимости (разная для каждой системы)
google_cost = google.get_cost()  # Стоимость Google запросов
yandex_cost = yandex.get_cost()  # Стоимость Yandex запросов

# Получение информации об ограничениях API
limits = google.get_api_limits()
print(f"Максимум потоков: {limits['max_concurrent_streams']}")
print(f"Дневной лимит Google: {limits['daily_limits']['google']:,} запросов")
print(f"Дневной лимит Yandex: {limits['daily_limits']['yandex']:,} запросов")

# Проверка индексации
is_indexed = google.check_indexing("https://python.org")

# Проверка доверия к домену
is_trusted = google.is_trust_domain("python.org")

⚡ Ограничения API

🔢 Потоки и производительность:

  • Максимум потоков: 10 для каждой системы (Google, Yandex, Wordstat)
  • Дневные лимиты:
    • Google: ~200,000 запросов/сутки
    • Yandex: ~150,000 запросов/сутки
  • Скорость ответа: 3-6 секунд (обычно), максимум 60 секунд

⏱️ Рекомендации по таймаутам:

# Используйте таймаут 60 секунд для надежности
google = GoogleClient(user_id=123, api_key="key", timeout=60)

# При низком таймауте есть риск потерять ответы
# Деньги за запрос снимаются, но результат может не прийти

🚨 Обработка ошибок потоков:

try:
    results = google.search("python")
except RateLimitError as e:
    if e.code in [110, 111, 115]:
        # Временные ошибки потоков - повторите запрос
        time.sleep(5)  # Подождите 5 секунд
        results = google.search("python")  # Повторите

🧪 Тестирование

# Запуск всех тестов
pytest

# Запуск с покрытием
pytest --cov=xmlriver_pro

# Запуск конкретных тестов
pytest tests/test_google.py
pytest tests/test_yandex.py

# Запуск с детальным выводом
pytest -v

📚 Документация

🤝 Вклад в проект

Issues и Pull Requests приветствуются на GitHub.

Установка для разработки

git clone https://github.com/Eapwrk/xmlriver-pro.git
cd xmlriver-pro
pip install -e ".[dev]"
pre-commit install

Запуск тестов

pytest
black xmlriver_pro tests
pylint xmlriver_pro
mypy xmlriver_pro

📄 Лицензия

MIT License. Подробности в LICENSE.

🙏 Благодарности

  • xmlriver.com за предоставление API
  • Python сообществу за экосистему
  • Контрибьюторам проекта

📞 Поддержка


XMLRiver Pro - Python клиент для API xmlriver.com

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xmlriver_pro-1.2.3.tar.gz (64.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xmlriver_pro-1.2.3-py3-none-any.whl (70.8 kB view details)

Uploaded Python 3

File details

Details for the file xmlriver_pro-1.2.3.tar.gz.

File metadata

  • Download URL: xmlriver_pro-1.2.3.tar.gz
  • Upload date:
  • Size: 64.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.8

File hashes

Hashes for xmlriver_pro-1.2.3.tar.gz
Algorithm Hash digest
SHA256 b65625b734224880c187cb492b62ae7bea1cb8088ec6ccbabce95b457b76a520
MD5 3cbf3d697cfac77b11f6be60afb12e43
BLAKE2b-256 30a705ff6aa73c2aac2a0b43b2a907f77ee43bae10b9968bc1e0f21e2a2ade7f

See more details on using hashes here.

File details

Details for the file xmlriver_pro-1.2.3-py3-none-any.whl.

File metadata

  • Download URL: xmlriver_pro-1.2.3-py3-none-any.whl
  • Upload date:
  • Size: 70.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.8

File hashes

Hashes for xmlriver_pro-1.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 3eaa156d5cf0fa80c78caa72176cb69d23aab607d9832e629a8e82298d770f1a
MD5 ff9a70c31bcafc6019fc24c51597390f
BLAKE2b-256 ca60166aeb86724f56797fb3320ebc9acc426cf8b05666f3a53e3182ab19ac6e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page