Quickstart (Python)
Build scripts that navigate the web using natural language instructions
This guide shows you how to use Stagehand with Steel browsers to create scripts that can interact with websites using natural language commands. We'll build a simple automation that extracts data from Hacker News and demonstrates search functionality.
Prerequisites
Ensure you have the following:
-
Python 3.8 or higher
-
A Steel API key (sign up here)
-
An OpenAI API key (get one here)
Step 1: Set up your environment
First, create a project directory and install the required packages:
# Create a project directorymkdir steel-stagehand-startercd steel-stagehand-starter# Install required packagespip install steel-sdk stagehand pydantic python-dotenv
Create a .env
file with your API keys:
1# .env2STEEL_API_KEY=your_steel_api_key_here3OPENAI_API_KEY=your_openai_api_key_here
Step 2: Create your data models
1import asyncio2import os3from dotenv import load_dotenv4from pydantic import BaseModel, Field5from steel import Steel6from stagehand import StagehandConfig, Stagehand78# Load environment variables9load_dotenv()1011# Get API keys from environment12STEEL_API_KEY = os.getenv("STEEL_API_KEY")13OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")1415# Define data models for structured extraction16class Story(BaseModel):17title: str = Field(..., description="Story title")18rank: int = Field(..., description="Story rank number")1920class Stories(BaseModel):21stories: list[Story] = Field(..., description="List of top stories")22
These models will help Stagehand extract structured data from web pages.
Step 3: Create a Steel browser session
Add the session creation logic to connect with Steel's cloud browsers:
1async def main():2print("🚀 Steel + Stagehand Automation")3print("=" * 50)45# Initialize Steel client6client = Steel(steel_api_key=STEEL_API_KEY)78# Create a new browser session9session = client.sessions.create()1011print("✅ Steel browser session created!")12print(f"View live session at: {session.session_viewer_url}")13
When you run this, you'll see a URL where you can watch your browser session live.
Step 4: Configure and connect Stagehand
Now we'll connect Stagehand to your Steel session:
1# Configure Stagehand to use Steel session2config = StagehandConfig(3env="LOCAL",4model_name="gpt-4o-mini",5model_api_key=OPENAI_API_KEY,6local_browser_launch_options={7"cdp_url": f"{session.websocket_url}&apiKey={STEEL_API_KEY}",8}9)1011# Initialize Stagehand12stagehand = Stagehand(config)13await stagehand.init()1415print("🤖 Stagehand connected to Steel browser")16
This connects Stagehand to your Steel browser session via Chrome DevTools Protocol.
Step 5: Navigate and extract data
Add the automation logic to navigate to a website and extract information:
1try:2# Navigate to Hacker News3print("📰 Navigating to Hacker News...")4await stagehand.page.goto("https://news.ycombinator.com")56# Extract top stories using AI7print("🔍 Extracting top stories...")8stories_data = await stagehand.page.extract(9"Extract the titles and ranks of the first 5 stories on the page",10schema=Stories11)1213# Display results14print("\n📋 Top 5 Hacker News Stories:")15for story in stories_data.stories:16print(f"{story.rank}. {story.title}")1718print("\n✅ Automation completed successfully!")1920except Exception as error:21print(f"❌ Error during automation: {error}")22
You'll see the extracted story titles and rankings printed to your console.
Step 6: Add proper cleanup
Always clean up your resources when finished:
1finally:2# Close Stagehand3if stagehand:4await stagehand.close()56# Release Steel session7if session and client:8client.sessions.release(session.id)9print("🧹 Resources cleaned up")1011# Run the automation12if __name__ == "__main__":13asyncio.run(main())14
Step 7: Run your automation
Execute your script:
You should see output like this:
🚀 Steel + Stagehand Automation==================================================✅ Steel browser session created!View live session at: https://app.steel.dev/v1/sessions/uuid🤖 Stagehand connected to Steel browser📰 Navigating to Hacker News...🔍 Extracting top stories...📋 Top 5 Hacker News Stories:1. Ask HN: What are you working on this week?2. Show HN: I built a tool to analyze my GitHub contributions3. The future of web development4. Why I switched from React to Vue5. Building scalable microservices with Go✅ Automation completed successfully!🧹 Resources cleaned up
Complete Example
Here's the complete script that puts all steps together:
1"""2AI-powered browser automation using Stagehand with Steel browsers.3https://github.com/steel-dev/steel-cookbook/tree/main/examples/steel-stagehand-python-starter4"""56import asyncio7import os8from dotenv import load_dotenv9from pydantic import BaseModel, Field10from steel import Steel11from stagehand import StagehandConfig, Stagehand1213# Load environment variables14load_dotenv()1516# Replace with your own API keys17STEEL_API_KEY = os.getenv("STEEL_API_KEY") or "your-steel-api-key-here"18OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") or "your-openai-api-key-here"1920# Define Pydantic models for structured data extraction21class Story(BaseModel):22title: str = Field(..., description="Story title")23rank: int = Field(..., description="Story rank number")2425class Stories(BaseModel):26stories: list[Story] = Field(..., description="List of top stories")2728async def main():29print("🚀 Steel + Stagehand Python Starter")30print("=" * 60)3132if STEEL_API_KEY == "your-steel-api-key-here":33print("⚠️ WARNING: Please replace 'your-steel-api-key-here' with your actual Steel API key")34print(" Get your API key at: https://app.steel.dev/settings/api-keys")35return3637if OPENAI_API_KEY == "your-openai-api-key-here":38print("⚠️ WARNING: Please replace 'your-openai-api-key-here' with your actual OpenAI API key")39print(" Get your API key at: https://platform.openai.com/")40return4142session = None43stagehand = None44client = None4546try:47print("\nCreating Steel session...")4849# Initialize Steel client with the API key from environment variables50client = Steel(steel_api_key=STEEL_API_KEY)5152session = client.sessions.create(53# === Basic Options ===54# use_proxy=True, # Use Steel's proxy network (residential IPs)55# proxy_url='http://...', # Use your own proxy (format: protocol://username:password@host:port)56# solve_captcha=True, # Enable automatic CAPTCHA solving57# session_timeout=1800000, # Session timeout in ms (default: 5 mins)58# === Browser Configuration ===59# user_agent='custom-ua', # Set a custom User-Agent60)6162print(f"\033[1;93mSteel Session created!\033[0m")63print(f"View session at \033[1;37m{session.session_viewer_url}\033[0m")6465config = StagehandConfig(66env="LOCAL",67model_name="gpt-4.1-mini",68model_api_key=OPENAI_API_KEY,69# Connect to Steel session via CDP70local_browser_launch_options={71"cdp_url": f"{session.websocket_url}&apiKey={STEEL_API_KEY}",72}73)7475stagehand = Stagehand(config)7677print("Initializing Stagehand...")78await stagehand.init()7980print("Connected to browser via Stagehand")8182print("Navigating to Hacker News...")83await stagehand.page.goto("https://news.ycombinator.com")8485print("Extracting top stories using AI...")8687stories_data = await stagehand.page.extract(88"Extract the titles and ranks of the first 5 stories on the page",89schema=Stories90)9192print("\n\033[1;92mTop 5 Hacker News Stories:\033[0m")93for story in stories_data.stories:94print(f"{story.rank}. {story.title}")9596print("\n\033[1;92mAutomation completed successfully!\033[0m")9798except Exception as error:99print(f"Error during automation: {error}")100import traceback101traceback.print_exc()102103finally:104if stagehand:105print("Closing Stagehand...")106try:107await stagehand.close()108except Exception as error:109print(f"Error closing Stagehand: {error}")110111if session and client:112print("Releasing Steel session...")113try:114client.sessions.release(session.id)115print("Steel session released successfully")116except Exception as error:117print(f"Error releasing session: {error}")118119# Run the main function120if __name__ == "__main__":121asyncio.run(main())
Next Steps
Now that you have a working Stagehand + Steel automation, try these enhancements:
-
Custom data extraction: Create your own Pydantic models for different websites
-
Complex interactions: Use
stagehand.page.act()
for clicking, typing, and navigation -
Multiple pages: Navigate through multi-step workflows
-
Error handling: Add retry logic and better error management
For more advanced features, check out:
-
Stagehand documentation for natural language automation
-
Steel API documentation for session management options
-
Steel GitHub examples for more integration patterns