Browser Harness

repository·main·Indexed 12 days ago

https://github.com/browser-use/browser-harness

A thin, editable Chrome DevTools Protocol (CDP) harness that connects LLMs directly to a real browser. Version 0.1.8 allows agents to write helper code and domain skills during execution for flexible browser automation, supporting local Chrome sessions, custom CDP endpoints, and Browser Use Cloud browsers.

Tokens
323.2K
Snippets
619
Records
966
Agent score
96%

What's inside Browser Harness

  1. Overview of Macrotrends Data Extraction Patterns

    main

    Macrotrends (https://www.macrotrends.net) provides historical financial and economic data. For read-only tasks, never use a browser; all data can be accessed via direct http_get requests to specific PHP endpoints or JSON APIs using a standard Mozilla/5.0 User-Agent. If you encounter 403 errors, switch to a Chrome User-Agent.

    There are three primary access patterns based on the data type:

    GoalPatternData VariableLatencyURL Component
    Stock OHLCV price historyDirect iframe PHPdataDaily~190msstock_price_history.php
    Stock market cap (daily)Direct iframe PHPchartData~200msmarket_cap.php
    Stock fundamentals (PE, revenue, margins)Direct iframe PHPchartData~140msfundamental_iframe.php or fundamental_metric.php
    S&P 500 / composite index chartschart_iframe_comp.phporiginalData~90mschart_iframe_comp.php
    Economic indicators (rates, yields, CPI)/economic-data/ JSON APIdata[] array~150ms/economic-data/
    Gold, commodity pricesEither pathdata[] or originalData~150msVaries
  2. Use the Facebook Pages mining skill

    main

    The Facebook Pages skill is designed to mine public Facebook Pages for recent posts, external URLs, and Page metadata. It is intended for read-only tasks such as harvesting content or links and is NOT for write actions like commenting, reacting, or messaging.

    Requirements:

    • A real Chrome browser driven by Browser Harness.
    • A logged-in session is highly recommended. While Pages are public, logged-out sessions encounter aggressive 'see more' gating and login interstitials that break the scrolling loop after approximately 5 posts.
  3. Use browser-harness for web interaction

    main

    Use browser-harness for any task requiring direct browser control via CDP, such as automation, scraping, testing, or interacting with web applications.

    When to use:

    • Tasks requiring interaction (click, type, navigate).
    • Accessing a user's logged-in session.
    • Handling JS rendering or bot-protected pages.
    • When a direct HTTP fetch fails or returns a shell page.

    When NOT to use:

    • For basic fetching of public information (use curl or a standard fetch tool instead).

    Note on Domain Skills: Domain skills are disabled by default. To enable them, set the environment variable BH_DOMAIN_SKILLS=1. When enabled, if a task is site-specific, you must read the files in $BH_AGENT_WORKSPACE/domain-skills/<site>/ before attempting a new approach.

    browser-harness <<'PY'
    print(page_info())
    PY
  4. Use the DuckDuckGo Instant Answer API

    main

    The DuckDuckGo Instant Answer API (https://api.duckduckgo.com) is a public, no-auth API that returns Wikipedia-sourced abstracts, infoboxes, and instant answers. It is designed for entity lookups and utility queries rather than general web search.

    Key Usage Guidelines

    • Do not use a browser: All requests are single http_get JSON calls.
    • Recommended Parameters: Always include skip_disambig=1 (to upgrade ambiguous terms to primary articles) and no_html=1 (to strip HTML tags from results).
    • Query Types: Results are categorized by a Type field:
      • A (Article): Specific entity with a full abstract.
      • D (Disambiguation): List of related topics for ambiguous terms.
      • E (Exclusive): Instant answers (calculators, converters, etc.).
      • "" (Empty): No match found.
  5. Overview of Substack Data Extraction via Public API

    main

    Substack exposes a public REST API at {publication}.substack.com/api/v1/ that allows for data extraction without authentication, API keys, or a browser. This works for both native .substack.com subdomains and custom domains.

    Capabilities:

    • List all posts from a publication (/api/v1/posts)
    • Fetch full post content by slug (/api/v1/posts/{slug})
    • Fetch post comments using the integer post_id (/api/v1/post/{post_id}/comments)
    • Read the RSS feed for lightweight metadata (/feed)

    Limitations:

    • Paywalled Content: For posts where audience is only_paid, the body_html and body_text fields return only a truncated HTML preview rather than the full article.
    • Search: There is no cross-publication search API available without a logged-in session.
    • Comments: The comments endpoint requires the integer post_id, not the post slug.
  6. Coordinate clicks vs JS clicks in iframes

    main

    When interacting with elements inside Shopify iframes, you have two options:

    1. Coordinate clicks (click(x, y)): These pass through iframes at the compositor level and work for simple interactions.
    2. JS clicks (via js() with target_id): These are generally more reliable for routine button taps because:
      • Element text content is stable across UI redesigns.
      • Device Pixel Ratio (DPR) scaling on retina displays is handled automatically.
      • React event handlers are guaranteed to fire (whereas CDP mouse events can sometimes hit transparent layers above the button).
  7. Macrotrends Scraping Gotchas and Tips

    main

    Keep these specific behaviors in mind when scraping Macrotrends:

    • URL Redirects: The URL you request might redirect. Always check the final URL with r.url and use that final URL as your Referer to ensure data consistency.
    • History Depth (yb parameter):
      • yb=1 returns ~250 records (last year).
      • yb=15 returns ~3772 records (last 15 years).
      • Omitting yb returns the full history.
    • Gold Data Columns: Gold price data contains two columns: close (inflation-adjusted price) and close1 (nominal USD price).
    • Economic API Fallback: If requesting a frequency (like A or Q) returns null, fall back to M (Monthly) or D (Daily).
    • Iframe Detection: To decide which extraction method to use, check the HTML content:
      • If chart_iframe_comp.php is present, use the originalData extraction pattern.
      • If highchartsURL is present, use the get_economic_data() API pattern.
  8. Handle Quora's double JSON encoding

    main

    Data within Quora's SSR (Server-Side Rendered) payloads is double-encoded. Each .push() argument is a JavaScript string literal containing JSON. To correctly parse this data into a Python dictionary, you must perform two steps:

    1. Decode the JS string escaping: Use json.loads('"' + raw + '"') to convert escaped characters (like \" to ").
    2. Parse the inner JSON: Pass the resulting string into a second json.loads() call to parse the actual object.

    Skipping either step will result in parse errors.

  9. Best practices for tab and target management

    main

    When automating browser tabs, follow these practical rules:

    • Visibility: switch_tab() is often insufficient if the user expects the browser window to visibly change focus. Use cdp("Target.activateTarget", targetId=tid) to force the tab to show.
    • Filtering: When calling list_tabs(), use include_chrome=False to avoid internal pages. Ignore chrome://omnibox-popup.top-chrome/ as it can appear as a fake page target.
    • Validation: If a page reports dimensions of w=0 h=0, you are likely attached to the wrong target or a non-window surface.
    • Dynamic UIs: For interfaces with dropdowns or modals, re-read element rectangles (rects) after opening them before attempting coordinate-based clicking.
  10. How to parse the Infobox field

    main

    The Infobox field is returned as a dictionary containing structured data about an entity. If no infobox is present, it returns an empty string "". Always check the type before processing.

    Structure

    • content: A list of dictionaries, each containing data_type, label, and value.
    • meta: A list of metadata items.

    Flattening the Infobox

    To convert the structured content list into a flat dictionary for easier access, use the following pattern:

    if isinstance(data['Infobox'], dict):
        fields = {item['label']: item['value'] for item in data['Infobox']['content']}
        # Example: fields['Founded'] == 'December 08, 2015'
    if isinstance(data['Infobox'], dict):
        fields = {item['label']: item['value'] for item in data['Infobox']['content']}
        # fields['Founded'] == 'December 08, 2015'
        # fields['Products'] == 'ChatGPT, GPT-5...'
  11. Understand BOSS直聘 Chat & Messaging Architecture

    main

    BOSS直聘 uses a hybrid messaging architecture for its chat functionality:

    • Conversation list: Loaded via WebSocket (ws6.zhipin.com) upon page load (not via REST).
    • Message history: Retrieved via the REST API /wapi/zpchat/geek/historyMsg.
    • Real-time messages: Delivered via WebSocket push from ws6.zhipin.com.

    IMPORTANT: This documentation covers read/retrieval mechanics only. Never send messages without explicit user permission.