Scraping
Extract content and structured data from web pages
Quick Start#
from pydantic import BaseModel
from notte_sdk import NotteClient
class HackerNewsPost(BaseModel):
title: str
url: str
points: int
author: str
class HackerNewsFeed(BaseModel):
posts: list[HackerNewsPost]
client = NotteClient()
result = client.scrape(
url="https://news.ycombinator.com",
response_format=HackerNewsFeed,
instructions="Extract the top 5 posts from the front page"
)
for i, post in enumerate(result.data.posts, 1):
print(f"{i}. {post.points} - {post.title}")Scraping Methods#
Notte provides two ways to scrape:
| Method | Use Case |
|---|---|
client.scrape(url) |
Quick, one-off scrapes |
session.scrape() |
Scraping after navigation or authentication |
Quick Scrape#
client = NotteClient()
# Returns markdown content
markdown = client.scrape("https://example.com")Session-Based Scrape#
For scraping after authentication or navigation:
with client.Session() as session:
session.execute(type="goto", url="https://example.com/login")
session.execute(type="fill", selector="input[name='email']", value="user@example.com")
session.execute(type="fill", selector="input[name='password']", value="password")
session.execute(type="click", selector="button[type='submit']")
session.execute(type="goto", url="https://example.com/dashboard")
content = session.scrape()Structured Extraction#
Extract data into typed objects using Pydantic models (Python) or Zod schemas (JavaScript). The extraction is powered by an LLM that understands the page content and extracts the specified fields.
Using Pydantic Models#
from pydantic import BaseModel
class Product(BaseModel):
name: str
price: float
description: str
client = NotteClient()
product = client.scrape(
"https://example.com/product", response_format=Product, instructions="Extract the product details"
)
print(f"Name: {product.name}, Price: {product.price}")Using Instructions Only#
For flexible extraction without a strict schema:
result = client.scrape(
"https://example.com/article", instructions="Extract the article title, author, and publication date"
)Extracting Lists#
class Article(BaseModel):
title: str
url: str
summary: str
class ArticleList(BaseModel):
articles: list[Article]
articles = client.scrape(
"https://news.example.com", response_format=ArticleList, instructions="Extract all articles from the homepage"
)Nested Structures#
class Address(BaseModel):
street: str
city: str
country: str
class Company(BaseModel):
name: str
description: str
address: Address
employee_count: int | None
company = client.scrape(
"https://example.com/about", response_format=Company, instructions="Extract company information including address"
)Image Extraction#
images = client.scrape("https://example.com/gallery", only_images=True)
for image in images:
print(f"URL: {image.url}")
print(f"Description: {image.description}")Configuration Options#
Content Filtering#
# Only main content (excludes navbars, footers, sidebars) - Default
markdown = client.scrape(url, only_main_content=True)
# Include all page content
markdown = client.scrape(url, only_main_content=False)Links and Images#
markdown = client.scrape(url, scrape_links=True) # Include links (default)
markdown = client.scrape(url, scrape_images=True) # Include images (off by default)Scoped Scraping#
with client.Session() as session:
content = session.scrape(selector="article.main-content")
content = session.scrape(selector="#product-details")Return Types#
The scrape method returns different types based on parameters:
| Parameters | Return Type |
|---|---|
| None | str (markdown) |
instructions |
StructuredData[BaseModel] |
response_format |
StructuredData[YourModel] |
only_images=True |
list[ImageData] |
Use Cases#
Data Collection#
class ProductInfo(BaseModel):
name: str
price: float
rating: float | None
reviews_count: int | None
urls = ["https://store.example.com/product/1", "https://store.example.com/product/2"]
products: list[ProductInfo] = []
for url in urls:
data = client.scrape(url, response_format=ProductInfo)
products.append(data)Content Monitoring#
Track how a pricing page changes over time by scraping it on a schedule and diffing against the previous version.
Research and Analysis#
class ResearchPaper(BaseModel):
title: str
authors: list[str]
abstract: str
publication_date: str | None
citations: int | None
result = client.scrape("https://papers.example.com/paper/123", response_format=ResearchPaper)Best Practices#
1. Use Specific Instructions#
# Good
instructions = "Extract the product name, price in USD, and availability status"
# Vague
instructions = "Get product info"2. Define Precise Schemas#
Match your schema to the actual page content, don't include fields the page might not have.
3. Handle Missing Data#
class Product(BaseModel):
name: str
price: float
discount_price: float | None = None
rating: float | None = None4. Scope Your Scrapes#
with client.Session() as session:
# Scrape only the main article, not comments or sidebar
content = session.scrape(selector="article.main")Next Steps#
-
Browser Sessions — Learn about session management
-
Browser Agents — Use AI agents for complex scraping
-
Vaults — Store credentials for authenticated scraping
-
Functions — Deploy scraping as serverless functions