Skip to main content
Glama

web-speed-agent

PyPI version Python License: GPL v3

Локальная автоматизация браузера + интеграция с Web Speed API для аутентифицированного извлечения данных с веб-сайтов.

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

pip install web-speed-agent
playwright install chromium

Хотите использовать это с Claude, Gemini или другими ИИ-клиентами?

Ознакомьтесь с Руководством по установке MCP-сервера — это самый простой способ позволить ИИ-агентам входить в систему и извлекать данные с помощью естественного языка.


Как это работает

Your machine                           Web Speed server
─────────────────────────────────      ──────────────────────────
Playwright browser (local)
  ↓ navigates, logs in, clicks
  ↓ gets page HTML
  ↓ (no passwords sent)
agent.extract(html)         ────────→  Advanced extraction engine
                            ←────────  Structured JSON

Учетные данные никогда не покидают ваш компьютер. Сервер видит только HTML.


Related MCP server: Agent Identity MCP Server

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

import asyncio
from web_speed_agent import Agent

async def main():
    agent = Agent(api_key="wsp_...")       # or set WEBSPEED_API_KEY env var

    # Public pages — no browser needed
    result = await agent.map("https://techcrunch.com/some-article/")
    print(result["article"]["sections"])

    # Authenticated pages — browser runs locally
    agent.store_credential("mysite", "me@example.com", "mypassword")

    async with agent.browser(session_name="mysite") as browser:
        page = await browser.new_page()
        await page.goto("https://mysite.com/login")

        username, password = agent.get_credential("mysite")
        await page.fill('[name="email"]', username)
        await page.fill('[name="password"]', password)
        await page.click('button[type="submit"]')
        await page.wait_for_load_state("networkidle")

        # Now on a logged-in page — extract it
        html = await page.content()
        result = await agent.extract(html, page_type="listing")
        print(result["listing"]["items"])

asyncio.run(main())

Получите API-ключ на getwebspeed.io.


Установка

Требования: Python 3.10+, API-ключ Web Speed

pip install web-speed-agent
playwright install chromium
export WEBSPEED_API_KEY="wsp_..."

Основные концепции

Agent

Основной класс. Управляет учетными данными, сессиями браузера и вызовами API.

from web_speed_agent import Agent

# API key from argument
agent = Agent(api_key="wsp_...")

# API key from environment variable (recommended)
# export WEBSPEED_API_KEY="wsp_..."
agent = Agent()

# Use as async context manager (auto-closes HTTP client)
async with Agent() as agent:
    ...

Извлечение данных с публичных страниц

Для страниц, не требующих входа в систему, браузер не нужен:

# Fetch + extract in one call
result = await agent.map("https://example.com/article")

# With JavaScript rendering (for heavy SPAs)
result = await agent.map("https://example.com/spa", js=True)

Извлечение данных с аутентифицированных страниц

Используйте локальную сессию браузера. Браузер запускается на вашем компьютере:

async with agent.browser(session_name="mysite") as browser:
    page = await browser.new_page()
    await page.goto("https://mysite.com/dashboard")
    html = await page.content()

result = await agent.extract(html)

Параметр session_name сохраняет файлы cookie в ~/.webspeed/sessions/<name>/, поэтому последующие запуски пропускают этап входа в систему.


Управление учетными данными

Учетные данные хранятся в системной связке ключей (macOS Keychain, Windows Credential Manager, Linux secret-tool). Они никогда не отправляются на серверы Web Speed.

# Store once
agent.store_credential("mysite", "me@example.com", "mypassword")

# Retrieve anywhere
username, password = agent.get_credential("mysite")

# Remove
agent.delete_credential("mysite")

Результат извлечения

Сервер возвращает структурированные данные с учетом типа страницы:

# Article
result = await agent.extract(html, page_type="article")
# result["page_type"]    → "article"
# result["title"]        → "Article Title"
# result["author"]       → "Jane Smith"
# result["published_date"] → "2026-05-06"
# result["article"]["sections"] → [{"heading": "...", "paragraphs": [...]}]
# result["article"]["links"]    → [{"text": "...", "url": "..."}]

# Product
result = await agent.extract(html, page_type="product")
# result["product"]["name"]         → "Wireless Headphones"
# result["product"]["price"]        → "$99.99"
# result["product"]["availability"] → "In Stock"
# result["product"]["rating"]       → "4.5"
# result["product"]["specs"]        → {"Battery": "30h", ...}

# Listing (search results, category pages)
result = await agent.extract(html, page_type="listing")
# result["listing"]["items"] → [{"title": "...", "url": "...", "price": "..."}]

# Auto-detect (default)
result = await agent.extract(html)
# result["page_type"] → "article" | "product" | "listing" | "other"

Все результаты включают engine: "advanced" — это на 60–85% эффективнее по токенам, чем необработанный HTML.


Примеры

Мониторинг цен

import asyncio
from web_speed_agent import Agent

async def check_price(url: str, site_name: str) -> str:
    async with Agent() as agent:
        agent.store_credential(site_name, "me@example.com", "password", overwrite=True)

        async with agent.browser(session_name=site_name) as browser:
            page = await browser.new_page()

            # Login
            await page.goto(f"https://{site_name}.com/login")
            user, pwd = agent.get_credential(site_name)
            await page.fill('[name="email"]', user)
            await page.fill('[name="password"]', pwd)
            await page.click('button[type="submit"]')
            await page.wait_for_load_state("networkidle")

            # Check product
            await page.goto(url)
            await page.wait_for_load_state("networkidle")
            html = await page.content()

        result = await agent.extract(html, page_type="product")
        return result.get("product", {}).get("price", "unknown")

price = asyncio.run(check_price("https://example.com/product/123", "example"))
print(f"Current price: {price}")

Чтение приватной панели управления

import asyncio
from web_speed_agent import Agent

async def get_dashboard_data():
    async with Agent() as agent:
        async with agent.browser(session_name="analytics") as browser:
            page = await browser.new_page()

            # Login (first run only — session persists after)
            creds = agent.get_credential("analytics")
            if not creds:
                agent.store_credential("analytics", "me@company.com", "password")
                creds = agent.get_credential("analytics")

            await page.goto("https://analytics.company.com/login")
            await page.fill('[name="email"]', creds[0])
            await page.fill('[name="password"]', creds[1])
            await page.click('button[type="submit"]')
            await page.wait_for_load_state("networkidle")

            # Navigate to dashboard
            await page.goto("https://analytics.company.com/dashboard")
            await page.wait_for_selector(".metrics-table", timeout=10000)
            html = await page.content()

        result = await agent.extract(html)
        return result

asyncio.run(get_dashboard_data())

Многостраничный парсинг с авторизацией

import asyncio
from web_speed_agent import Agent

async def scrape_inbox():
    async with Agent() as agent:
        async with agent.browser(session_name="webmail") as browser:
            page = await browser.new_page()

            # Login
            await page.goto("https://mail.example.com/login")
            user, pwd = agent.get_credential("webmail")
            await page.fill('[name="username"]', user)
            await page.fill('[name="password"]', pwd)
            await page.click('[type="submit"]')
            await page.wait_for_load_state("networkidle")

            # Scrape multiple pages
            emails = []
            for page_num in range(1, 4):
                await page.goto(f"https://mail.example.com/inbox?page={page_num}")
                await page.wait_for_load_state("networkidle")
                html = await page.content()
                result = await agent.extract(html, page_type="listing")
                emails.extend(result.get("listing", {}).get("items", []))

        return emails

asyncio.run(scrape_inbox())

Интеграция с ИИ-агентами (MCP)

Включенный MCP-сервер позволяет Claude Desktop, Gemini CLI и любому MCP-совместимому агенту использовать SDK напрямую. Агент может входить в систему, перемещаться по страницам, нажимать кнопки и извлекать данные — и все это с помощью естественного языка.

Запуск MCP-сервера:

WEBSPEED_API_KEY="wsp_..." python3 agent_mcp_server.py

Добавление в Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "web-speed-agent": {
      "command": "python3",
      "args": ["/path/to/agent_mcp_server.py"],
      "env": {
        "WEBSPEED_API_KEY": "wsp_..."
      }
    }
  }
}

Добавление в Gemini CLI (~/.gemini/settings.json):

{
  "mcpServers": {
    "web-speed-agent": {
      "command": "python3.11",
      "args": ["/path/to/agent_mcp_server.py"],
      "env": {
        "WEBSPEED_API_KEY": "wsp_...",
        "PYTHONPATH": "/path/to/web-speed-agent"
      }
    }
  }
}

Затем скажите агенту:

"Сохрани мои учетные данные для united — имя пользователя me@example.com, пароль mypassword"

"Войди на united.com и найди мне самый дешевый авиабилет из SFO в JFK на следующую пятницу"

Доступные инструменты MCP:

Инструмент

Описание

store_credential

Сохранить логин в системную связку ключей

login

Открыть браузер + войти в систему

navigate

Перейти по URL в активной сессии

extract_page

Получить структурированные данные с текущей страницы

click

Нажать на кнопку или ссылку

fill_field

Ввести данные в поле формы

submit_form

Отправить форму

close_browser

Завершить сессию браузера

account_info

Проверить баланс кредитов API


Справочник API

Agent

Agent(
    api_key: str | None = None,
    server_url: str | None = None,
    config_dir: str = "~/.webspeed",
    headless: bool = True,
)

Параметр

Описание

api_key

API-ключ Web Speed. Если не задан, используется переменная окружения WEBSPEED_API_KEY.

server_url

Переопределение URL сервера API. По умолчанию: https://api.getwebspeed.io.

config_dir

Директория для конфигурации, сессий и логов. По умолчанию: ~/.webspeed.

headless

Запуск браузера в безголовом режиме. По умолчанию: True.


agent.browser()

agent.browser(
    session_name: str | None = None,
    headless: bool | None = None,
    proxy: str | None = None,
) -> ManagedBrowser

Возвращает асинхронный контекстный менеджер. Внутри блока вызовите .new_page(), чтобы получить объект Page из Playwright.

Параметр

Описание

session_name

Сохранение cookie в ~/.webspeed/sessions/<name>/. None = без сохранения.

headless

Переопределение параметра headless экземпляра для этой сессии.

proxy

URL прокси, например, "socks5://localhost:1080".

Имена сессий должны состоять из букв, цифр, дефисов или подчеркиваний, максимум 64 символа.


agent.extract()

await agent.extract(
    html: str,
    page_type: str = "auto",
) -> dict

Отправляет HTML в Web Speed API. Стоимость: 1 кредит.

Параметр

Описание

html

Строка с необработанным HTML (например, из page.content()).

page_type

"article", "product", "listing" или "auto".


agent.map()

await agent.map(
    url: str,
    js: bool = False,
) -> dict

Получает и извлекает данные с публичного URL через сервер. Локальный браузер не требуется. Стоимость: 1 кредит.

Параметр

Описание

url

URL страницы. Должен начинаться с http:// или https://.

js

Рендерить JavaScript перед извлечением.


agent.account()

await agent.account() -> dict

Возвращает: credits, tier, status, lifetime (всего/успешно/ошибки).


agent.store_credential()

agent.store_credential(
    site: str,
    username: str,
    password: str,
    overwrite: bool = False,
) -> None

Сохраняет в системную связку ключей. Вызывает CredentialError, если учетные данные существуют и overwrite=False.


agent.get_credential()

agent.get_credential(site: str) -> tuple[str, str] | None

Возвращает (username, password) или None, если не найдено.


agent.delete_credential()

agent.delete_credential(site: str) -> None

Удаляет учетные данные из связки ключей.


Исключения

from web_speed_agent import (
    WebSpeedError,          # Base exception
    AuthenticationError,    # Invalid/missing API key
    InsufficientCreditsError, # No credits remaining
    APIError,               # API returned 4xx/5xx
    RateLimitError,         # 429 Too Many Requests
    CredentialError,        # Keychain error
    BrowserError,           # Playwright error
    NetworkError,           # Timeout or DNS failure
    PlaywrightNotInstalledError, # Run: playwright install chromium
)
from web_speed_agent import Agent, InsufficientCreditsError, NetworkError

try:
    result = await agent.extract(html)
except InsufficientCreditsError:
    print("Out of credits — top up at getwebspeed.io")
except NetworkError as e:
    print(f"Connection failed: {e}")

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

Переменные окружения

Переменная

Описание

WEBSPEED_API_KEY

API-ключ (рекомендуется вместо файла конфигурации)

WEBSPEED_SERVER_URL

Переопределение URL сервера (должен начинаться с https://)

Файл конфигурации

~/.webspeed/config.yaml — создается автоматически при первом запуске. Права доступа установлены на 0o600 (только для владельца).

api:
  server_url: https://api.getwebspeed.io
  timeout: 30

browser:
  headless: true

Файлы сессий

Сохраненные сессии браузера хранятся в ~/.webspeed/sessions/<name>/storage.json.

  • Права доступа: 0o600 (только для владельца)

  • Содержит: cookies, localStorage, sessionStorage

  • Можно безопасно удалить: агент повторно пройдет аутентификацию при следующем запуске


Безопасность

Что покидает ваш компьютер

Когда вы вызываете agent.extract(html), HTML страницы отправляется в Web Speed API для обработки. Все остальное остается локально.

Данные

Куда отправляются

Учетные данные для входа

Никогда не покидают ваш компьютер (только системная связка ключей)

Cookies / сессия браузера

Никогда не покидают ваш компьютер (локальный Playwright)

HTML страницы

Отправляется по HTTPS в Web Speed API для извлечения

Извлеченный JSON

Возвращается вам

Очистка HTML (включена по умолчанию)

Перед передачей любого HTML SDK автоматически очищает его локально:

  • Удаляются встроенные блоки <script> и <style>

  • Скрытые поля форм с именами, связанными с аутентификацией (csrf, token, nonce, session и т.д.), очищаются

  • Атрибуты содержимого конфиденциальных тегов <meta> удаляются

  • HTML-комментарии удаляются

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

# Default: scrubbing is on
result = await agent.extract(html)

# Turn off only if the page has no sensitive data
result = await agent.extract(html, scrub=False)

# Or scrub manually and inspect before sending
from web_speed_agent import scrub
clean_html = scrub(raw_html)
print(clean_html)  # inspect what will be sent
result = await agent.extract(clean_html, scrub=False)

Обработка данных на стороне сервера

  • HTML обрабатывается только в оперативной памяти — никогда не записывается на диск, не логируется и не кэшируется

  • Страницы с защитой авторизацией никогда не кэшируются — страницы, требующие входа, явно исключены из общего реестра

  • Логи использования хранят только: хэш вашего API-ключа, хэш URL (или "sdk-extract"), временную метку и обнаруженный тип страницы — никакого контента

  • Никакого необработанного HTML в ответах об ошибках — исключения очищаются перед возвратом любой ошибки

Другие меры защиты

  • Учетные данные хранятся в системной связке ключей, никогда не записываются в файлы и не отправляются на серверы

  • Файлы сессий записываются с правами 0o600 (чтение/запись только для владельца)

  • Директория конфигурации создается с правами 0o700

  • TLS всегда проверяетсяverify=True для всех HTTP-вызовов, отключить нельзя

  • HTTPS принудительноserver_url должен начинаться с https://, обычный HTTP отклоняется

  • Предотвращение обхода путей — имена сессий проверяются по списку разрешенных символов [a-zA-Z0-9_-]

  • Никакого логирования учетных данных — пароли никогда не появляются в логах или сообщениях об ошибках


Лицензия

GNU General Public License v3.0 — см. LICENSE.

Использование Web Speed API регулируется Условиями предоставления услуг Web Speed.

A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Provides an MCP-native agent browser that enables autonomous agents to perceive and interact with web pages through stealth browsing, identity borrowing, and WAAP detection.
    9
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP-capable runtimes to read agent message rooms, sign and post public messages, and create or verify Ed25519 contribution proofs for Technocore.
    MIT

View all related MCP servers

Related MCP Connectors

  • Agent-first web hosting: deploy sites, apps, databases and domains over MCP.

  • Hosted AgentLux MCP server for marketplace, identity, creator, services, and social flows.

  • MCP Server for agents to onboard, pay, and provision services autonomously with InFlow

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Dominic-Pi-Sunyer/web-speed-agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server