<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: AlterLab</title>
    <description>The latest articles on DEV Community by AlterLab (@alterlab).</description>
    <link>https://dev.to/alterlab</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3842661%2F6ea3b67f-3a2b-423f-b726-51041ab344e6.png</url>
      <title>DEV Community: AlterLab</title>
      <link>https://dev.to/alterlab</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alterlab"/>
    <language>en</language>
    <item>
      <title>How to Scrape Uber Eats Data: Complete Guide for 2026</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Wed, 08 Jul 2026 15:20:55 +0000</pubDate>
      <link>https://dev.to/alterlab/how-to-scrape-uber-eats-data-complete-guide-for-2026-1990</link>
      <guid>https://dev.to/alterlab/how-to-scrape-uber-eats-data-complete-guide-for-2026-1990</guid>
      <description>&lt;h1&gt;
  
  
  How to Scrape Uber Eats Data: Complete Guide for 2026
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This guide covers extracting publicly accessible data. Always review a site's robots.txt and Terms of Service before scraping.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;To scrape Uber Eats restaurant data, use AlterLab's API with Python or Node.js to handle anti-bot protections automatically. Target public menu pages, extract structured fields like item names and prices via CSS selectors or Cortex AI, and scale responsibly with rate limiting. Start at T1 tier—the API promotes to T3/T4 as needed for JavaScript-dependent content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why collect food data from Uber Eats?
&lt;/h2&gt;

&lt;p&gt;Food delivery data powers competitive intelligence for restaurants and analysts. Track real-time pricing trends across cuisines to adjust your menu strategy. Monitor competitor promotions and new dish launches for market timing. Aggregate nutritional information for dietary app development or supply chain forecasting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical challenges
&lt;/h2&gt;

&lt;p&gt;Uber Eats implements standard anti-bot systems: rate limiting by IP, User-Agent validation, and JavaScript challenges that block headless browsers without proper fingerprinting. Raw HTTP requests (T1/T2) typically return CAPTCHAs or empty responses for menu pages. AlterLab's &lt;a href="https://dev.to/smart-rendering-api"&gt;Smart Rendering API&lt;/a&gt; manages proxy rotation, realistic headers, and headless Chrome instances to access public food data while respecting site protections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start with AlterLab API
&lt;/h2&gt;

&lt;p&gt;See the &lt;a href="https://dev.to/docs/quickstart/installation"&gt;Getting started guide&lt;/a&gt; for SDK setup. Below are examples scraping a public Uber Eats restaurant menu page (replace &lt;code&gt;YOUR_API_KEY&lt;/code&gt; and the URL with your target).&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="scrape_ubereats-com.py" {3-5}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;br&gt;
response = client.scrape("&lt;a href="https://www.ubereats.com/menu/example-restaurant%22" rel="noopener noreferrer"&gt;https://www.ubereats.com/menu/example-restaurant"&lt;/a&gt;)&lt;br&gt;
print(response.text[:500])  # First 500 chars of HTML&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;




```javascript title="scrape_ubereats-com.js" {3-5}

const client = new AlterLab({ apiKey: "YOUR_API_KEY" });
const response = await client.scrape("https://www.ubereats.com/menu/example-restaurant");
console.log(response.text.slice(0, 500));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;```bash title="Terminal"&lt;br&gt;
curl -X POST &lt;a href="https://api.alterlab.io/v1/scrape" rel="noopener noreferrer"&gt;https://api.alterlab.io/v1/scrape&lt;/a&gt; \&lt;br&gt;
  -H "X-API-Key: YOUR_KEY" \&lt;br&gt;
  -d '{"url": "&lt;a href="https://www.ubereats.com/menu/example-restaurant%22%7D" rel="noopener noreferrer"&gt;https://www.ubereats.com/menu/example-restaurant"}&lt;/a&gt;'&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Extracting structured data
Uber Eats menu pages use consistent HTML structures. Target `.menu-item` containers for dish details:



```python title="extract_menu_items.py"

from parsel import Selector

client = alterlab.Client("YOUR_API_KEY")
html = client.scrape("https://www.ubereats.com/menu/example-restaurant").text
selector = Selector(text=html)

for item in selector.css(".menu-item"):
    name = item.css(".item-name::text").get()
    price = item.css(".price::text").get()
    print(f"{name.strip()}: {price}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Node.js equivalent using &lt;code&gt;cheerio&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```javascript title="extract-menu-items.js"&lt;/p&gt;

&lt;p&gt;const client = new AlterLab({ apiKey: "YOUR_API_KEY" });&lt;br&gt;
const html = await client.scrape("&lt;a href="https://www.ubereats.com/menu/example-restaurant%22" rel="noopener noreferrer"&gt;https://www.ubereats.com/menu/example-restaurant"&lt;/a&gt;);&lt;br&gt;
const $ = cheerio.load(html);&lt;/p&gt;

&lt;p&gt;$(".menu-item").each((_, el) =&amp;gt; {&lt;br&gt;
  const name = $(el).find(".item-name").text().trim();&lt;br&gt;
  const price = $(el).find(".price").text().trim();&lt;br&gt;
  console.log(&lt;code&gt;${name}: ${price}&lt;/code&gt;);&lt;br&gt;
});&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Structured JSON extraction with Cortex
For typed output without manual parsing, use AlterLab's Cortex extraction API. Define a JSON schema for menu items:



```python title="extract_ubereats-com_structured.py"

client = alterlab.Client("YOUR_API_KEY")
result = client.extract(
    url="https://www.ubereats.com/menu/example-restaurant",
    schema={
        "type": "object",
        "properties": {
            "restaurant_name": {"type": "string"},
            "menu_items": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string"},
                        "price": {"type": "number"},
                        "description": {"type": "string"},
                        "rating": {"type": "number"}
                    },
                    "required": ["name", "price"]
                }
            }
        }
    }
)
print(result.data)  # Validated JSON output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cost breakdown
&lt;/h2&gt;

&lt;p&gt;AlterLab's pricing scales with technical difficulty. Uber Eats public menu pages typically require T3 (Stealth) due to anti-bot measures, but the API starts at T1 and promotes automatically—you only pay for the successful tier.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Cost per Request&lt;/th&gt;
&lt;th&gt;Cost per 1,000&lt;/th&gt;
&lt;th&gt;Requests per $1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;T1 — Curl&lt;/td&gt;
&lt;td&gt;Static HTML, no JS needed&lt;/td&gt;
&lt;td&gt;$0.0002&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;td&gt;5,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T2 — HTTP&lt;/td&gt;
&lt;td&gt;Standard pages with headers&lt;/td&gt;
&lt;td&gt;$0.0003&lt;/td&gt;
&lt;td&gt;$0.30&lt;/td&gt;
&lt;td&gt;3,333&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T3 — Stealth&lt;/td&gt;
&lt;td&gt;Protected pages, anti-bot active&lt;/td&gt;
&lt;td&gt;$0.002&lt;/td&gt;
&lt;td&gt;$2.00&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T4 — Browser&lt;/td&gt;
&lt;td&gt;Full JS rendering required&lt;/td&gt;
&lt;td&gt;$0.004&lt;/td&gt;
&lt;td&gt;$4.00&lt;/td&gt;
&lt;td&gt;250&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T5 — CAPTCHA&lt;/td&gt;
&lt;td&gt;CAPTCHA solving + JS rendering&lt;/td&gt;
&lt;td&gt;$0.02&lt;/td&gt;
&lt;td&gt;$20.00&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://dev.to/pricing"&gt;View full pricing details&lt;/a&gt;. Note: AlterLab auto-escalates tiers—start at T1 and pay only for the level that succeeds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting&lt;/strong&gt;: Stay under 1 request/second per IP to avoid triggering protections (AlterLab's internal queues help manage this).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robots.txt&lt;/strong&gt;: Check &lt;code&gt;https://www.ubereats.com/robots.txt&lt;/code&gt; for crawl delays and disallowed paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic content&lt;/strong&gt;: Use &lt;code&gt;wait_for&lt;/code&gt; parameters in AlterLab API to ensure menu items load before extraction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headers&lt;/strong&gt;: AlterLab rotates realistic browser fingerprints—avoid overriding &lt;code&gt;User-Agent&lt;/code&gt; unless necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error handling&lt;/strong&gt;: Implement retries with exponential backoff for transient failures (HTTP 429/503).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scaling up
&lt;/h2&gt;

&lt;p&gt;For large-scale menu data collection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Batch requests&lt;/strong&gt;: Process 100 URLs concurrently using AlterLab's &lt;code&gt;/batch&lt;/code&gt; endpoint (reduces overhead).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduling&lt;/strong&gt;: Use cron expressions via AlterLab's scheduling API for daily menu updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data storage&lt;/strong&gt;: Save extracted JSON to cloud storage (S3/GCS) with timestamps for historical analysis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsible scaling&lt;/strong&gt;: Monitor response codes—if 429s increase, reduce concurrency or add delays.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Uber Eats public menu data is accessible via AlterLab's API without building custom anti-bot solutions.&lt;/li&gt;
&lt;li&gt;Start with CSS selectors for simple extraction; use Cortex AI for schema-validated output.&lt;/li&gt;
&lt;li&gt;Budget ~$0.002/request for most Uber Eats scraping tasks (T3 tier).&lt;/li&gt;
&lt;li&gt;Always prioritize compliance: review ToS, rate limit, and scrape only publicly visible information.&lt;/li&gt;
&lt;li&gt;Scale responsibly with batch processing and scheduling for ongoing market intelligence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://dev.to/scrape/uber-eats"&gt;Explore our dedicated Uber Eats scraping guide&lt;/a&gt; for advanced patterns and maintenance tips.&lt;/p&gt;

</description>
      <category>python</category>
      <category>javascript</category>
      <category>antibot</category>
      <category>automation</category>
    </item>
    <item>
      <title>How to Scrape Redfin Data: Complete Guide for 2026</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Wed, 08 Jul 2026 15:20:54 +0000</pubDate>
      <link>https://dev.to/alterlab/how-to-scrape-redfin-data-complete-guide-for-2026-26lh</link>
      <guid>https://dev.to/alterlab/how-to-scrape-redfin-data-complete-guide-for-2026-26lh</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Scrape Redfin with AlterLab API. Send a request with the target URL. Receive JSON response.&lt;/p&gt;

&lt;p&gt;This guide covers extracting publicly accessible data. Always review a site's robots.txt and Terms of Service before scraping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why collect real-estate data from Redfin
&lt;/h2&gt;

&lt;p&gt;Market research teams monitor price trends. Investors track inventory changes. Analysts build property databases. Each use case needs fresh public listings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical challenges
&lt;/h2&gt;

&lt;p&gt;Real‑estate sites like Redfin enforce anti-bot rules. They check headers, rate limits, and JavaScript execution. Simple curl calls often fail. Use AlterLab smart rendering API to bypass these hurdles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start with AlterLab API
&lt;/h2&gt;

&lt;p&gt;Follow the Getting started guide for setup. Then run a Python script or a Node.js snippet.&lt;/p&gt;

&lt;p&gt;Python example&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="scrape_redfin-com.py" {3-5}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;br&gt;
response = client.scrape("&lt;a href="https://www.redfin.com/city/32/DCA/virginia%22" rel="noopener noreferrer"&gt;https://www.redfin.com/city/32/DCA/virginia"&lt;/a&gt;)&lt;br&gt;
print(response.text)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Node.js example


```javascript title="scrape_redfin-com.js" {3-5}

const client = new AlterLab({ apiKey: "YOUR_API_KEY" });
const response = await client.scrape("https://www.redfin.com/city/32/DCA/virginia");
console.log(response.text);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;cURL example&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```bash title="Terminal" {3-5}&lt;br&gt;
curl -X POST &lt;a href="https://api.alterlab.io/v1/scrape" rel="noopener noreferrer"&gt;https://api.alterlab.io/v1/scrape&lt;/a&gt; \&lt;br&gt;
  -H "X-API-Key: YOUR_KEY" \&lt;br&gt;
  -d '{"url": "&lt;a href="https://www.redfin.com/city/32/DCA/virginia%22%7D" rel="noopener noreferrer"&gt;https://www.redfin.com/city/32/DCA/virginia"}&lt;/a&gt;'&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Extracting structured data
Identify key elements on a Redfin listing page. Common public fields include title, price, rating, and description. Use CSS selectors that match these elements. Example selectors: .heading-location, .price, .rating, .description.

## Structured JSON extraction with Cortex
Cortex extracts typed JSON without manual parsing. Define a schema that matches the fields you need. The API returns clean data ready for analysis.



```python title="extract_redfin-com_structured.py"

client = alterlab.Client("YOUR_API_KEY")
result = client.extract(
    url="https://www.redfin.com/city/32/DCA/virginia",
    schema={
        "type": "object",
        "properties": {
            "title": {"type": "string"},
            "price": {"type": "number"},
            "rating": {"type": "number"},
            "description": {"type": "string"}
        }
    }
)
print(result.data)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cost breakdown
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Cost per Request&lt;/th&gt;
&lt;th&gt;Cost per 1,000&lt;/th&gt;
&lt;th&gt;Requests per $1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;T1 - Curl&lt;/td&gt;
&lt;td&gt;Static HTML, no JS needed&lt;/td&gt;
&lt;td&gt;$0.0002&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;td&gt;5,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T2 - HTTP&lt;/td&gt;
&lt;td&gt;Standard pages with headers&lt;/td&gt;
&lt;td&gt;$0.0003&lt;/td&gt;
&lt;td&gt;$0.30&lt;/td&gt;
&lt;td&gt;3,333&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T3 - Stealth&lt;/td&gt;
&lt;td&gt;Protected pages, anti-bot active&lt;/td&gt;
&lt;td&gt;$0.002&lt;/td&gt;
&lt;td&gt;$2.00&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T4 - Browser&lt;/td&gt;
&lt;td&gt;Full JS rendering required&lt;/td&gt;
&lt;td&gt;$0.004&lt;/td&gt;
&lt;td&gt;$4.00&lt;/td&gt;
&lt;td&gt;250&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T5 - CAPTCHA&lt;/td&gt;
&lt;td&gt;CAPTCHA solving + JS rendering&lt;/td&gt;
&lt;td&gt;$0.02&lt;/td&gt;
&lt;td&gt;$20.00&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For Redfin start at T1. If the call fails AlterLab upgrades the tier automatically. You only pay for the tier that succeeds. See pricing details at &lt;a href="https://dev.to/pricing"&gt;AlterLab pricing&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices
&lt;/h2&gt;

&lt;p&gt;Throttle your calls. Respect rate limits set by the target site. Use the AlterLab monitoring endpoint to track scrape health. Store results in a durable location. Review the site’s Terms of Service before large scale collection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling up
&lt;/h2&gt;

&lt;p&gt;Create schedules with cron expressions. Use webhook destinations to receive results in real time. Process large datasets in chunks to avoid memory spikes. Monitor API usage to stay within budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;p&gt;Scraping Redfin works best with AlterLab. Choose the right tier for the page complexity. Follow legal and technical guidelines. Your pipeline will stay stable and affordable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related resources
&lt;/h2&gt;

&lt;p&gt;Explore the full Redfin scraping guide at &lt;a href="https://dev.to/scrape/redfin"&gt;Redfin scraping guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start with AlterLab API
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/docs/quickstart/installation"&gt;Getting started guide&lt;/a&gt; walks you through API key creation. Use the Python or Node.js snippets above to test a single URL. For batch jobs integrate the &lt;a href="https://dev.to/smart-rendering-api"&gt;Smart Rendering API&lt;/a&gt; to handle dynamic content.&lt;/p&gt;

</description>
      <category>cloudflare</category>
      <category>python</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>How to Give Your AI Agent Access to AngelList Data</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Tue, 07 Jul 2026 11:35:47 +0000</pubDate>
      <link>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-angellist-data-24ke</link>
      <guid>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-angellist-data-24ke</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Extract AngelList job listings with AlterLab’s Extract API or Search API to get clean JSON for your agent, handle anti bot automatically, and feed results directly into your LLM context window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI agents need AngelList data
&lt;/h2&gt;

&lt;p&gt;AI agents that monitor startup ecosystems can use AngelList data for several practical tasks. Job postings reveal hiring trends and emerging technologies. Founder activity signals market interest and potential investment targets. Investor watchlists can be built from publicly listed fund activity. These use cases feed directly into RAG pipelines and knowledge base updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why raw HTTP requests fail for agents
&lt;/h2&gt;

&lt;p&gt;Direct HTTP calls to AngelList often trigger rate limiting and bot detection. The site uses JavaScript rendering for many job listings, meaning a simple GET request returns an empty page until the client executes scripts. Agents that attempt to scrape without a headless browser see many empty responses and must retry, consuming extra tokens and time. CAPTCHAs appear when request patterns look automated, forcing manual intervention or additional workarounds. Without a dedicated proxy pool, the source IP can be blocked after a few hundred requests, halting the pipeline entirely. All of this creates unpredictable latency and unnecessary cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting your agent to AngelList via AlterLab
&lt;/h2&gt;

&lt;p&gt;AlterLab provides two paths for agentic access. Use the Extract API for structured output or the Scrape API for raw HTML when you need full control. Both endpoints automatically rotate proxies across residential IP pools, handle CAPTCHA solving, and retry failed requests internally. The Extract API returns JSON that matches a schema you define, eliminating the need for downstream parsing. The Scrape API returns the full HTML payload, which you can process further if you need custom extraction logic. Because the service manages anti bot protection, agents can focus on data consumption rather than bot evasion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structured extraction example
&lt;/h3&gt;



&lt;p&gt;```python title="agent_angellist-com.py" {3-7}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;/p&gt;

&lt;h1&gt;
  
  
  Structured extraction — get clean data without parsing HTML
&lt;/h1&gt;

&lt;p&gt;result = client.extract(&lt;br&gt;
    url="&lt;a href="https://angellist.com/example-page" rel="noopener noreferrer"&gt;https://angellist.com/example-page&lt;/a&gt;",&lt;br&gt;
    schema={"title": "string", "price": "string", "description": "string"}&lt;br&gt;
)&lt;br&gt;
print(result.data)  # Clean structured dict, ready for your LLM&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


### Raw HTML fetch example


```bash title="Terminal" {2-5}
curl -X POST https://api.alterlab.io/api/v1/extract/templates/{template_id} \
  -H "X-API-Key: YOUR_KEY" \
  -d '{"url": "https://angellist.com/example-page", "schema": {"title": "string", "price": "string"}}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;See the quickstart guide for installation instructions. Refer to the Extract API docs for schema options. Check the pricing page for cost details.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using the Search API for AngelList queries
&lt;/h2&gt;

&lt;p&gt;Search API lets agents query AngelList with natural language filters. You can specify filters such as location, funding stage, or industry to narrow results. An example query for “seed stage SaaS founders in New York” returns a list of matching profiles with titles, URLs, and basic metadata. The response includes a stable schema that lists each result’s ID, name, and tags. Pagination is supported via a cursor parameter, allowing you to retrieve large result sets in batches. Rate limits are enforced per API key, so you should implement back‑off logic when approaching the quota.&lt;/p&gt;
&lt;h2&gt;
  
  
  MCP integration
&lt;/h2&gt;

&lt;p&gt;AlterLab offers an MCP server that integrates with Claude Cursor and GPT agents. Add the server URL to your agent configuration to call AlterLab tools natively. Documentation and quickstart guides are available at the AlterLab for AI Agents page.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building a startup job market monitoring pipeline
&lt;/h2&gt;

&lt;p&gt;An end‑to‑end pipeline might look like this. The agent requests data from AngelList through the service. The service returns structured JSON that matches a schema you define, such as job title, location, and tags. The agent passes this JSON to an LLM for summarization, sentiment analysis, or extraction of key signals. The resulting insight can be stored in a vector database for similarity search later. Schedule the function with a cron expression to run daily, and use monitoring to detect changes in job count or new postings. When a change is detected, trigger a notification or update the knowledge base automatically.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="pipeline_example.py" {4-9}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;/p&gt;

&lt;p&gt;def get_jobs():&lt;br&gt;
    resp = client.extract(&lt;br&gt;
        url="&lt;a href="https://angellist.com/startups" rel="noopener noreferrer"&gt;https://angellist.com/startups&lt;/a&gt;",&lt;br&gt;
        schema={"title": "string", "location": "string", "tags": "string"}&lt;br&gt;
    )&lt;br&gt;
    return resp.data&lt;/p&gt;

&lt;p&gt;jobs = get_jobs()&lt;/p&gt;

&lt;h1&gt;
  
  
  Send jobs to an LLM for summarization
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Store embeddings in a vector database
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Update knowledge base on schedule
&lt;/h1&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Schedule the function with a cron expression to run daily, and use monitoring to detect changes in job count or new postings. When a change is detected, trigger a notification or update the knowledge base automatically.

## Key takeaways
Agents can access AngelList data reliably through the Extract and Search APIs. Structured output reduces parsing overhead and token waste, keeping cost predictable. MCP integration simplifies tool calling for major LLM platforms such as Claude, GPT, and Gemini. Always respect robots.txt and rate limits when scaling scrapes, and monitor response health to avoid pipeline breaks.

&amp;lt;div data-infographic="stats"&amp;gt;
  &amp;lt;div data-stat data-value="99.2%" data-label="Request Success Rate"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-stat data-value="&amp;lt;1s" data-label="Avg Structured Response"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-stat data-value="0" data-label="HTML Parsing Required"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div data-infographic="steps"&amp;gt;
  &amp;lt;div data-step data-number="1" data-title="Agent requests data" data-description="LLM agent calls AlterLab tool with target URL"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="2" data-title="AlterLab fetches plus extracts" data-description="Handles anti bot and returns structured JSON"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="3" data-title="Agent uses clean data" data-description="No parsing, no retries, data goes straight to LLM context"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div data-infographic="try-it" data-url="https://angellist.com" data-description="Extract structured AngelList data for your AI agent"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>antibot</category>
      <category>automation</category>
      <category>aiagents</category>
      <category>api</category>
    </item>
    <item>
      <title>Building a Scalable Proxy Rotation System for AI Agents</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Tue, 07 Jul 2026 11:05:47 +0000</pubDate>
      <link>https://dev.to/alterlab/building-a-scalable-proxy-rotation-system-for-ai-agents-29kk</link>
      <guid>https://dev.to/alterlab/building-a-scalable-proxy-rotation-system-for-ai-agents-29kk</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;A scalable proxy rotation system for AI agents continuously monitors tunnel health, automatically removes unhealthy endpoints, and switches to fresh proxies without interrupting the agent’s workflow. This approach keeps success rates high and reduces manual intervention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Proxy Rotation Matters for AI Agents
&lt;/h2&gt;

&lt;p&gt;AI agents often perform repetitive HTTP(S) requests to gather data, interact with APIs, or drive headless browsers. Target websites employ rate limiting, IP‑based blocking, or bot detection that can halt an agent after a handful of requests. By rotating proxies, each request appears to come from a different IP address, spreading the load and lowering the probability of triggering defenses.&lt;/p&gt;

&lt;p&gt;A robust rotation system does more than randomly pick an IP. It must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify that a proxy is actually reachable and returns expected content.&lt;/li&gt;
&lt;li&gt;Remove failing proxies quickly to avoid wasted attempts.&lt;/li&gt;
&lt;li&gt;Re‑introduce proxies after a cool‑down period, assuming they may recover.&lt;/li&gt;
&lt;li&gt;Provide low‑latency failover so the agent experiences minimal delay.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Core Components
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Proxy Pool&lt;/strong&gt; – a mutable list of candidate endpoints (HTTP/HTTPS or SOCKS5).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health Checker&lt;/strong&gt; – a background process that periodically tests each proxy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selector&lt;/strong&gt; – chooses the next proxy based on health scores and recent usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failover Handler&lt;/strong&gt; – switches to an alternative proxy when a request fails or times out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics Store&lt;/strong&gt; – records latency, success/failure counts, and timestamps for each proxy.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Health Verification Techniques
&lt;/h2&gt;

&lt;p&gt;A proxy is considered healthy if it meets three criteria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Connectivity&lt;/strong&gt;: TCP handshake succeeds within a timeout (e.g., 2 s).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response Validity&lt;/strong&gt;: A simple GET request to a known endpoint (like &lt;code&gt;https://httpbin.org/ip&lt;/code&gt;) returns the expected IP address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Average latency over the last N checks stays below a threshold (e.g., 500 ms).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any check fails, the proxy’s health score is decremented. After M consecutive failures, it is marked unhealthy and removed from the active pool. Successful checks increment the score, allowing recovery.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Health Checker (Python)
&lt;/h3&gt;



&lt;p&gt;```python title="health_checker.py" {2-8}&lt;/p&gt;

&lt;p&gt;from typing import List, Dict&lt;/p&gt;

&lt;p&gt;class ProxyHealthChecker:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, proxies: List[str], test_url: str = "&lt;a href="https://httpbin.org/ip%22):" rel="noopener noreferrer"&gt;https://httpbin.org/ip"):&lt;/a&gt;&lt;br&gt;
        self.proxies = proxies&lt;br&gt;
        self.test_url = test_url&lt;br&gt;
        self.scores: Dict[str, int] = {p: 10 for p in proxies}&lt;br&gt;
        self._session: aiohttp.ClientSession | None = None&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async def start(self):
    self._session = aiohttp.ClientSession()
    asyncio.create_task(self._run())

async def _run(self):
    while True:
        await asyncio.gather(*[self._check(p) for p in self.proxies])
        await asyncio.sleep(30)  # check every 30 s

async def _check(self, proxy: str):
    try:
        timeout = aiohttp.ClientTimeout(total=5)
        async with self._session.get(self.test_url, proxy=proxy, timeout=timeout) as resp:
            if resp.status == 200:
                data = await resp.json()
                if data.get("origin"):  # basic validity
                    self.scores[proxy] = min(self.scores[proxy] + 1, 20)
                else:
                    self.scores[proxy] = max(self.scores[proxy] - 2, 0)
            else:
                self.scores[proxy] = max(self.scores[proxy] - 2, 0)
    except Exception:
        self.scores[proxy] = max(self.scores[proxy] - 2, 0)

def get_healthy(self, threshold: int = 10) -&amp;gt; List[str]:
    return [p for p, s in self.scores.items() if s &amp;gt;= threshold]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

The checker maintains a score per proxy; the selector uses `get_healthy()` to fetch the current viable list.

## Selector and Failover Logic
The selector picks the proxy with the highest health score that hasn’t been used recently (to balance load). When a request raises an exception or returns a non‑2xx status, the failover handler instantly retries with the next candidate.

### Example Selector
python
title="selector.py" {2-6}
def select_proxy(healthy: List[str], used_recently: set[str]) -&amp;gt; str | None:
    candidates = [p for p in healthy if p not in used_recently]
    if not candidates:
        return healthy[0] if healthy else None
    # simple round‑robin among candidates; replace with weighted choice if desired
    return candidates[0]


```python
Used proxies are tracked in a short‑lived set (e.g., last 5 requests) to avoid hammering the same endpoint.

## Putting It All Together – Request Wrapper
The wrapper combines the health checker, selector, and failover logic into a single `fetch` function that AI agents can call.

python
title="agent_fetch.py" {3-12}

from health_checker import ProxyHealthChecker
from selector import select_proxy

class ResilientFetcher:
    def __init__(self, proxy_list: List[str]):
        self.checker = ProxyHealthChecker(proxy_list)
        self.used_recently: set[str] = set()
        self.max_retry = 3

    async def start(self):
        await self.checker.start()

    async def fetch(self, url: str) -&amp;gt; str:
        attempt = 0
        while attempt &amp;lt; self.max_retry:
            healthy = self.checker.get_healthy()
            proxy = select_proxy(healthy, self.used_recently)
            if not proxy:
                raise RuntimeError("No healthy proxies available")

            try:
                timeout = aiohttp.ClientTimeout(total=10)
                async with aiohttp.ClientSession() as session:
                    async with session.get(url, proxy=proxy, timeout=timeout) as resp:
                        if resp.status == 200:
                            self.used_recently.add(proxy)
                            if len(self.used_recently) &amp;gt; 5:
                                self.used_recently.pop()
                            return await resp.text()
                        # treat non‑2xx as failure for this proxy
                        raise aiohttp.ClientError(f"Bad status {resp.status}")
            except Exception as exc:
                # penalize the proxy and try next
                self.checker.scores[proxy] = max(self.checker.scores[proxy] - 3, 0)
                attempt += 1
                await asyncio.sleep(0.5 * attempt)  # brief backoff
        raise RuntimeError(f"Failed to fetch {url} after {self.max_retry} attempts")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fetcher updates the used‑recently set to spread load and relies on the health checker’s scores to avoid bad proxies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Equivalent cURL Workflow
&lt;/h2&gt;

&lt;p&gt;For environments where a Python SDK isn’t available, the same logic can be scripted with shell commands and a small state file.&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
title="fetch_with_proxy.sh" {2-9}&lt;/p&gt;

&lt;h1&gt;
  
  
  !/usr/bin/env scroll="nowrap"
&lt;/h1&gt;

&lt;p&gt;PROXY_FILE="/tmp/proxies.list"&lt;br&gt;
SCORE_FILE="/tmp/proxy_scores.txt"&lt;br&gt;
TEST_URL="&lt;a href="https://httpbin.org/ip" rel="noopener noreferrer"&gt;https://httpbin.org/ip&lt;/a&gt;"&lt;br&gt;
TARGET_URL="$1"&lt;/p&gt;

&lt;h1&gt;
  
  
  Initialize scores if missing
&lt;/h1&gt;

&lt;p&gt;if [[ ! -f $SCORE_FILE ]]; then&lt;br&gt;
    while IFS= read -r line; do&lt;br&gt;
        echo "$line 10" &amp;gt;&amp;gt; $SCORE_FILE&lt;br&gt;
    done &amp;lt; $PROXY_FILE&lt;br&gt;
fi&lt;/p&gt;

&lt;p&gt;get_healthy() {&lt;br&gt;
    awk '$2 &amp;gt;= 10 {print $1}' $SCORE_FILE&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;update_score() {&lt;br&gt;
    local proxy=$1 delta=$2&lt;br&gt;
    awk -v p="$proxy" -v d="$delta" '&lt;br&gt;
        $1==p { $2+=d; if($2&amp;lt;0) $2=0; if($2&amp;gt;20) $2=20 }&lt;br&gt;
        { print }&lt;br&gt;
    ' $SCORE_FILE &amp;gt; "${SCORE_FILE}.tmp" &amp;amp;&amp;amp; mv "${SCORE_FILE}.tmp" $SCORE_FILE&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;attempt=0&lt;br&gt;
MAX_ATTEMPTS=3&lt;br&gt;
while (( attempt &amp;lt; MAX_ATTEMPTS )); do&lt;br&gt;
    healthy=$(get_healthy)&lt;br&gt;
    if [[ -z $healthy ]]; then&lt;br&gt;
        echo "No healthy proxies" &amp;gt;&amp;amp;2; exit 1&lt;br&gt;
    fi&lt;br&gt;
    # pick first healthy line (round‑robin)&lt;br&gt;
    proxy=$(echo "$healthy" | head -n1)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resp=$(curl -s -x "$proxy" --max-time 10 -w "%{http_code}" "$TARGET_URL" -o /dev/null || echo "000")
if [[ $resp -eq 200 ]]; then
    # success: boost score
    update_score "$proxy" 2
    echo "Success via $proxy"
    exit 0
else
    # failure: penalize
    update_score "$proxy" -3
    ((attempt++))
    sleep $((attempt * 1))
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;done&lt;br&gt;
echo "All attempts failed" &amp;gt;&amp;amp;2&lt;br&gt;
exit 1&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

This script mirrors the Python version: it reads a proxy list, maintains scores, picks a healthy endpoint, and retries on failure.

## Infographic: Proxy Rotation Flow
&amp;lt;div data-infographic="steps"&amp;gt;
  &amp;lt;div data-step data-number="1" data-title="Initialize Proxy List" data-description="Load HTTP/SOCKS5 endpoints from config or service discovery."&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="2" data-title="Run Health Checks" data-description="Background pings test connectivity, latency, and IP echo validity."&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="3" data-title="Score Update" data-description="Successful checks increase score; failures decrease it."&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="4" data-title="Select Proxy" data-description="Choose highest‑scoring unused proxy for the next request."&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="5" data-title="Execute Request" data-description="Send the agent’s HTTP request via the selected proxy."&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="6" data-title="Evaluate Outcome" data-description="On success, mildly boost score; on failure, penalize and retry with alternate proxy."&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

## TryIt: Test Proxy Health with AlterLab
To see how a managed scraping API handles proxy rotation and health verification, you can run a quick test against a sample endpoint.
&amp;lt;div data-infographic="try-it" data-url="https://example.com" data-description="Try scraping this page with AlterLab"&amp;gt;&amp;lt;/div&amp;gt;

## Integration Tips
- **Pool Size**: Maintain at least 3× the expected concurrent request count to ensure healthy fallbacks.
- **Test URL Choice**: Use a lightweight, reliable endpoint that returns the caller’s IP (e.g., `https://httpbin.org/ip`). Avoid heavy pages that add noise to health checks.
- **Metrics Export**: Expose scores and latency via Prometheus or similar to observe trends and tune thresholds.
- **Legal Compliance**: Only rotate proxies for accessing publicly available data; respect each site’s terms of service and rate‑limit policies.

## Why a Managed Service Helps
Building and operating a health‑checking layer at scale demands continuous monitoring, fast failure detection, and intelligent rerouting. Services like AlterLab’s [web scraping API](https://alterlab.io/web-scraping-api-python) already embed automatic proxy rotation, tunnel health verification, and smart retry logic, letting engineers focus on the data extraction logic rather than networking plumbing. For quick experimentation, the [Python SDK](https://alterlab.io/web-scraping-api-python) provides a ready‑to‑use client, while the [API reference](https://alterlab.io/docs) details all available parameters.

## Takeaway
A scalable proxy rotation system combines continuous health verification, intelligent scoring, and fast failover to keep AI agents productive despite anti‑bot measures. By separating concerns—pool management, health checking, selection, and request handling failures—you create a resilient layer that can be tuned, observed, and replaced with a managed offering as your needs evolve. Start small, measure success rates, and iterate on thresholds to achieve the reliability your pipelines demand.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>proxies</category>
      <category>automation</category>
      <category>headlessbrowsers</category>
      <category>datapipelines</category>
    </item>
    <item>
      <title>How to Scrape Best Buy Data: Complete Guide for 2026</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Mon, 06 Jul 2026 15:05:47 +0000</pubDate>
      <link>https://dev.to/alterlab/how-to-scrape-best-buy-data-complete-guide-for-2026-400f</link>
      <guid>https://dev.to/alterlab/how-to-scrape-best-buy-data-complete-guide-for-2026-400f</guid>
      <description>&lt;p&gt;This guide covers extracting publicly accessible data. Always review a site's robots.txt and Terms of Service before scraping.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Scrape Best Buy product pages using AlterLab's API with Python or Node.js. Start at T1 tier, let auto-escalation handle anti-bot, and extract structured data via CSS selectors or Cortex AI. For typical product pages, expect T2-T3 tiers ($0.0003-$0.002/request).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why collect e-commerce data from Best Buy?
&lt;/h2&gt;

&lt;p&gt;Best Buy's public product pages offer valuable signals for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Price monitoring&lt;/strong&gt;: Track competitor pricing strategies across electronics categories&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inventory analysis&lt;/strong&gt;: Gauge stock levels and product availability trends&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review aggregation&lt;/strong&gt;: Collect customer sentiment for market research&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical challenges
&lt;/h2&gt;

&lt;p&gt;Best Buy implements standard e-commerce anti-bot measures including rate limiting, IP reputation checks, and JavaScript rendering requirements. Raw HTTP requests often fail with 403/429 responses or incomplete HTML. AlterLab's &lt;a href="https://dev.to/smart-rendering-api"&gt;Smart Rendering API&lt;/a&gt; automatically handles proxy rotation, header management, and headless browser rendering to access public product data reliably.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start with AlterLab API
&lt;/h2&gt;

&lt;p&gt;See the &lt;a href="https://dev.to/docs/quickstart/installation"&gt;Getting started guide&lt;/a&gt; for setup. Below are examples scraping a Best Buy product page:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="scrape_bestbuy-com.py" {3-5}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;br&gt;
response = client.scrape("&lt;a href="https://www.bestbuy.com/site/apple-iphone-15-pro-128gb-black-titanium/6501342.p%22" rel="noopener noreferrer"&gt;https://www.bestbuy.com/site/apple-iphone-15-pro-128gb-black-titanium/6501342.p"&lt;/a&gt;)&lt;br&gt;
print(response.text)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;




```javascript title="scrape_bestbuy-com.js" {3-5}

const client = new AlterLab({ apiKey: "YOUR_API_KEY" });
const response = await client.scrape("https://www.bestbuy.com/site/apple-iphone-15-pro-128gb-black-titanium/6501342.p");
console.log(response.text);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;```bash title="Terminal"&lt;br&gt;
curl -X POST &lt;a href="https://api.alterlab.io/v1/scrape" rel="noopener noreferrer"&gt;https://api.alterlab.io/v1/scrape&lt;/a&gt; \&lt;br&gt;
  -H "X-API-Key: YOUR_KEY" \&lt;br&gt;
  -d '{"url": "&lt;a href="https://www.bestbuy.com/site/apple-iphone-15-pro-128gb-black-titanium/6501342.p%22%7D" rel="noopener noreferrer"&gt;https://www.bestbuy.com/site/apple-iphone-15-pro-128gb-black-titanium/6501342.p"}&lt;/a&gt;'&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Extracting structured data
AlterLab returns raw HTML by default. Use CSS selectors to extract specific public data points:



```python title="parse_bestbuy-com.py"

from parsel import Selector

client = alterlab.Client("YOUR_API_KEY")
html = client.scrape("https://www.bestbuy.com/site/apple-iphone-15-pro-128gb-black-titanium/6501342.p").text
selector = Selector(text=html)

title = selector.css(".sku-header h1::text").get()
price = selector.css(".price-current .sr-only::text").get()
rating = selector.css(".rating-stars::attr('aria-label')").get()

print({"title": title.strip() if title else None, 
       "price": price, 
       "rating": rating})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Structured JSON extraction with Cortex
&lt;/h2&gt;

&lt;p&gt;For typed data without parsing HTML, use AlterLab's Cortex AI extraction:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="extract_bestbuy-com_structured.py"&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;br&gt;
result = client.extract(&lt;br&gt;
    url="&lt;a href="https://www.bestbuy.com/site/apple-iphone-15-pro-128gb-black-titanium/6501342.p" rel="noopener noreferrer"&gt;https://www.bestbuy.com/site/apple-iphone-15-pro-128gb-black-titanium/6501342.p&lt;/a&gt;",&lt;br&gt;
    schema={&lt;br&gt;
        "type": "object",&lt;br&gt;
        "properties": {&lt;br&gt;
            "title": {"type": "string"},&lt;br&gt;
            "price": {"type": "number"},&lt;br&gt;
            "rating": {"type": "number"},&lt;br&gt;
            "availability": {"type": "string"},&lt;br&gt;
            "sku": {"type": "string"}&lt;br&gt;
        }&lt;br&gt;
    }&lt;br&gt;
)&lt;br&gt;
print(result.data)  # Typed JSON output: {"title": "...", "price": 999.99, ...}&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Cost breakdown
AlterLab auto-escalates tiers — start at T1 and pay only for the tier that succeeds. For Best Buy product pages (standard anti-bot protections), expect T2 or T3 tiers. See [AlterLab pricing](/pricing) for full details.

| Tier | Use Case | Cost per Request | Cost per 1,000 | Requests per $1 |
|------|----------|-----------------|----------------|------------------|
| T1 — Curl | Static HTML, no JS needed | $0.0002 | $0.20 | 5,000 |
| T2 — HTTP | Standard pages with headers | $0.0003 | $0.30 | 3,333 |
| T3 — Stealth | Protected pages, anti-bot active | $0.002 | $2.00 | 500 |
| T4 — Browser | Full JS rendering required | $0.004 | $4.00 | 250 |
| T5 — CAPTCHA | CAPTCHA solving + JS rendering | $0.02 | $20.00 | 50 */

&amp;lt;div data-infographic="stats"&amp;gt;
  &amp;lt;div data-stat data-value="99999.2%" data-label="Success Rate"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-stat data-value="1.2s" data-label="Avg Response"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-stat data-value="$0.002" data-label="Per Request (T3)"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

## Best practices
- **Rate limiting**: Start with 1 request/second, adjust based on response headers
- **Robots.txt**: Check `https://www.bestbuy.com/robots.txt` for crawl delays and disallowed paths
- **Dynamic content**: Use Cortex AI or wait for network idle state instead of fixed timeouts
- **Error handling**: Implement retry logic with exponential backoff for 429/5xx responses
- **Data freshness**: For price monitoring, schedule requests during off-peak hours (2-5 AM local store time)

## Scaling up
For large-scale data collection:
- **Batch requests**: Use AlterLab's batch endpoint (up to 100 URLs/request)
- **Scheduling**: Implement cron-based scrapes via AlterLab's scheduling feature
- **Storage**: Stream results directly to data warehouses or cloud storage
- **Monitoring**: Set up alerts for failed requests or data anomalies

&amp;lt;div data-infographic="steps"&amp;gt;
  &amp;lt;div data-step data-number="1" data-title="Configure scraper" data-title="Configure scraper" data-description="Set URL, parameters, and extraction schema"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="2" data-title="Execute request" data-description="AlterLab handles tier selection and anti-bot"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="3" data-title="Process results" data-description="Store structured JSON or trigger webhooks"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

## Key takeaways
- AlterLab simplifies Best Buy scraping by managing anti-bot, proxies, and rendering
- Extract public product data via CSS selectors or Cortex AI for type-safe JSON
- Costs scale with complexity: $0.0002-$0.004/request depending on required tier
- Always comply with robots.txt, rate limits, and Terms of Service
- See the [Best Buy scraping guide](/scrape/best-buy) for advanced patterns

&amp;lt;div data-infographic="try-it" data-url="https://bestbuy.com" data-description="Try scraping Best Buy with AlterLab"&amp;gt;&amp;lt;/div&amp;gt;
Hit reply if you have questions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>antibot</category>
      <category>automation</category>
      <category>proxies</category>
      <category>dataextraction</category>
    </item>
    <item>
      <title>Designing a Fault-Tolerant Proxy Rotation Wrapper</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Mon, 06 Jul 2026 10:55:39 +0000</pubDate>
      <link>https://dev.to/alterlab/designing-a-fault-tolerant-proxy-rotation-wrapper-4ccb</link>
      <guid>https://dev.to/alterlab/designing-a-fault-tolerant-proxy-rotation-wrapper-4ccb</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;A fault-tolerant proxy rotation wrapper ensures high success rates by validating proxy tunnels via a lightweight health check before passing them to a headless browser. This architecture prevents browser timeouts, reduces resource waste, and ensures that only active, high-quality IPs are used for data extraction.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Naive Proxy Rotation
&lt;/h2&gt;

&lt;p&gt;Most basic proxy implementations follow a "try-and-fail" pattern. The application picks a random proxy from a list, attempts to load a page, and if the request fails, it catches the exception and tries again. &lt;/p&gt;

&lt;p&gt;For headless browsers (Playwright, Puppeteer, Selenium), this is inefficient. Loading a full browser instance and navigating to a URL is resource-heavy. When a proxy is dead, the browser often hangs for 30 to 60 seconds before hitting a timeout. In a high-concurrency environment, this leads to "zombie" browser processes and massive latency spikes.&lt;/p&gt;

&lt;p&gt;A professional architecture separates &lt;strong&gt;tunnel verification&lt;/strong&gt; from &lt;strong&gt;page execution&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing the Health-Check Wrapper
&lt;/h2&gt;

&lt;p&gt;The goal is to create a layer that acts as a gatekeeper. Instead of the browser requesting a page directly, it requests a "healthy" proxy from the wrapper. The wrapper verifies the proxy's connectivity and latency before returning it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Verification Logic
&lt;/h3&gt;

&lt;p&gt;A healthy proxy must meet three criteria before it is deemed viable:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;TCP Connectivity&lt;/strong&gt;: The tunnel must be open.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Response&lt;/strong&gt;: The proxy must return a valid status code from a neutral endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency Threshold&lt;/strong&gt;: The response time must be under a specific limit (e.g., &amp;lt; 2000ms) to prevent slow-loading pages.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Implementation in Python
&lt;/h2&gt;

&lt;p&gt;The following implementation uses a &lt;code&gt;ProxyManager&lt;/code&gt; class to maintain a pool of proxies and a &lt;code&gt;verify_proxy&lt;/code&gt; method to ensure health.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="proxy_manager.py" {15-24}&lt;/p&gt;

&lt;p&gt;from collections import deque&lt;/p&gt;

&lt;p&gt;class ProxyManager:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, proxy_list, timeout=2):&lt;br&gt;
        self.pool = deque(proxy_list)&lt;br&gt;
        self.timeout = timeout&lt;br&gt;
        self.unhealthy_proxies = {}&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def verify_proxy(self, proxy):
    """Check if a proxy is healthy using a lightweight request."""
    try:
        # Use a neutral, fast endpoint for verification
        response = requests.get(
            "https://httpbin.org/ip", 
            proxies={"http": proxy, "https": proxy}, 
            timeout=self.timeout
        )
        return response.status_code == 200
    except requests.RequestException:
        return False

def get_healthy_proxy(self):
    """Rotates and verifies proxies until a healthy one is found."""
    attempts = 0
    max_attempts = len(self.pool)

    while attempts &amp;lt; max_attempts:
        proxy = self.pool[0]
        self.pool.rotate(-1)  # Move to end of list

        # Check if proxy is currently in cooldown
        if proxy in self.unhealthy_proxies:
            if time.time() &amp;lt; self.unhealthy_proxies[proxy]:
                attempts += 1
                continue

        if self.verify_proxy(proxy):
            return proxy

        # Mark as unhealthy for 5 minutes
        self.unhealthy_proxies[proxy] = time.time() + 300
        attempts += 1

    return None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Integrating with Headless Browsers

Once you have a verified proxy, you can inject it into your browser launch configuration. This ensures that your browser session starts with a known-good connection, reducing the chance of an immediate failure.



```python title="scraper.py" {8-12}
from playwright.sync_api import sync_playwright
from proxy_manager import ProxyManager

proxies = ["http://user:pass@ip1:port", "http://user:pass@ip2:port"]
manager = ProxyManager(proxies)

def run_scrape(url):
    proxy_server = manager.get_healthy_proxy()
    if not proxy_server:
        print("No healthy proxies available")
        return

    with sync_playwright() as p:
        browser = p.chromium.launch(
            proxy={"server": proxy_server}, 
            headless=True
        ) # Start browser with verified proxy
        page = browser.new_page()
        page.goto(url)
        print(page.title())
        browser.close()

run_scrape("https://example.com")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handling Advanced Anti-Bot Systems
&lt;/h2&gt;

&lt;p&gt;While proxy rotation handles connectivity, it does not solve fingerprinting or sophisticated behavioral analysis. High-value targets often employ &lt;a href="https://alterlab.io/smart-rendering-api" rel="noopener noreferrer"&gt;anti-bot handling&lt;/a&gt; that detects headless browsers regardless of the IP address.&lt;/p&gt;

&lt;p&gt;To scale this, you need to combine proxy rotation with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Header Randomization&lt;/strong&gt;: Rotating User-Agents and Accept-Language headers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TLS Fingerprinting&lt;/strong&gt;: Ensuring the TLS handshake matches a real browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JS Rendering&lt;/strong&gt;: Using a browser that can execute JavaScript to prove it is not a simple script.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For those who prefer not to manage the infrastructure of health-checks and rotations, utilizing a &lt;a href="https://alterlab.io/web-scraping-api-python" rel="noopener noreferrer"&gt;Python scraping API&lt;/a&gt; abstracts the entire proxy management layer, providing a single endpoint that handles rotation and verification internally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Comparison
&lt;/h2&gt;

&lt;p&gt;Using a pre-verification wrapper significantly changes the failure profile of a scraping pipeline.&lt;/p&gt;


&lt;div class="table-wrapper-paragraph"&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;table&gt;

    &lt;thead&gt;

      &lt;tr&gt;

        &lt;th&gt;Metric&lt;/th&gt;

        &lt;th&gt;Naive Rotation&lt;/th&gt;

        &lt;th&gt;Health-Check Wrapper&lt;/th&gt;

      &lt;/tr&gt;

    &lt;/thead&gt;

    &lt;tbody&gt;

      &lt;tr&gt;

        &lt;td&gt;Avg. Request Latency&lt;/td&gt;

        &lt;td&gt;High (due to timeouts)&lt;/td&gt;

        &lt;td&gt;Low (pre-verified)&lt;/td&gt;

      &lt;/tr&gt;

      &lt;tr&gt;

        &lt;td&gt;Browser Resource Use&lt;/td&gt;

        &lt;td&gt;Wasted on dead IPs&lt;/td&gt;

        &lt;td&gt;Optimized&lt;/td&gt;

      &lt;/tr&gt;

      &lt;tr&gt;

        &lt;td&gt;Success Rate&lt;/td&gt;

        &lt;td&gt;Variable&lt;/td&gt;

        &lt;td&gt;Consistent&lt;/td&gt;

      &lt;/tr&gt;

    &lt;/tbody&gt;

  &lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Managing State and Cooldowns
&lt;/h2&gt;

&lt;p&gt;In a production system, you should not just rotate proxies but also track their "health score." If a proxy fails three times in a row on the target site (even if it passes the &lt;code&gt;httpbin&lt;/code&gt; health check), it should be flagged as "site-blocked" and put into a longer cooldown period.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Circuit Breaker Pattern
&lt;/h3&gt;

&lt;p&gt;Implementing a circuit breaker prevents your system from hammering a target site with IPs that are already flagged. If your failure rate exceeds a certain threshold (e.g., 20% over 100 requests), the circuit "opens," and the system pauses all requests for a set duration to avoid a total IP range ban.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Decouple Verification&lt;/strong&gt;: Never let the headless browser be the primary tool for testing proxy health.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Lightweight Pings&lt;/strong&gt;: Use fast, neutral endpoints to verify tunnels before assigning them to heavy browser instances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement Cooldowns&lt;/strong&gt;: Track unhealthy proxies in a dictionary with timestamps to avoid repeated attempts on dead tunnels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Combine Layers&lt;/strong&gt;: Pair your rotation wrapper with TLS fingerprinting and JS rendering for the highest success rates.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>proxies</category>
      <category>python</category>
      <category>headlessbrowsers</category>
      <category>datapipelines</category>
    </item>
    <item>
      <title>How to Scrape Stack Overflow Data in 2026</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Sun, 05 Jul 2026 14:53:45 +0000</pubDate>
      <link>https://dev.to/alterlab/how-to-scrape-stack-overflow-data-in-2026-32c2</link>
      <guid>https://dev.to/alterlab/how-to-scrape-stack-overflow-data-in-2026-32c2</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Scrape stack overflow with Python, Node.js, or cURL via the AlterLab API. Use T1 for static pages, T3 for protected content, and Cortex for structured JSON extraction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why collect developer data from Stack Overflow?
&lt;/h2&gt;

&lt;p&gt;Market research, price monitoring, and analytical dashboards often rely on publicly listed questions, answers, and tags. The data is openly available and can inform product decisions without violating access rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical challenges
&lt;/h2&gt;

&lt;p&gt;Stack Overflow enforces rate limits and delivers much of its content through JavaScript. Simple HTTP requests fail on heavy query patterns or on pages that load content dynamically. To handle these realities, use the Smart Rendering API for full page rendering and automatic bot detection mitigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start with AlterLab API
&lt;/h2&gt;

&lt;p&gt;Create an account and obtain an API key. Then follow the Getting started guide at /docs/quickstart/installation to install the SDK. Below are minimal examples in Python, Node.js, and cURL that target a public question page.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="scrape_stackoverflow-com.py" {3-5}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;br&gt;
response = client.scrape("&lt;a href="https://stackoverflow.com/questions%22" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions"&lt;/a&gt;)&lt;br&gt;
print(response.text)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;




```javascript title="scrape_stackoverflow-com.js" {2-4}

const client = new AlterLab({ apiKey: "YOUR_API_KEY" });
const response = await client.scrape("https://stackoverflow.com/questions");
console.log(response.text);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;```bash title="Terminal" {3}&lt;br&gt;
curl -X POST &lt;a href="https://api.alterlab.io/v1/scrape" rel="noopener noreferrer"&gt;https://api.alterlab.io/v1/scrape&lt;/a&gt; \&lt;br&gt;
  -H "X-API-Key: YOUR_KEY" \&lt;br&gt;
  -d '{"url": "&lt;a href="https://stackoverflow.com/questions%22%7D" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions"}&lt;/a&gt;'&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Extracting structured data
Public pages expose predictable HTML structures. For example, question titles use `&amp;lt;h1 class="question-title"&amp;gt;`, while answer counts appear in `&amp;lt;div class="answer-count"&amp;gt;`. Use CSS selectors that match these classes to pull the exact fragments you need.

## Structured JSON extraction with Cortex
Cortex simplifies schema‑driven extraction. The following Python sample pulls a question’s title, score, and answer count into a typed JSON object.



```python title="extract_stackoverflow-com_structured.py" {3-6}

client = alterlab.Client("YOUR_API_KEY")
result = client.extract(
    url="https://stackoverflow.com/questions",
    schema={
        "type": "object",
        "properties": {
            "title": {"type": "string"},
            "score": {"type": "number"},
            "answer_count": {"type": "number"}
        }
    }
)
print(result.data)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cost breakdown
&lt;/h2&gt;

&lt;p&gt;Pricing depends on the tier you select. The table below shows cost per request and per 1,000 requests.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Cost per Request&lt;/th&gt;
&lt;th&gt;Cost per 1,000&lt;/th&gt;
&lt;th&gt;Requests per $1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;T1 — Curl&lt;/td&gt;
&lt;td&gt;Static HTML, no JS needed&lt;/td&gt;
&lt;td&gt;$0.0002&lt;/td&gt;
&lt;td&gt;$0.20&lt;/td&gt;
&lt;td&gt;5,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T2 — HTTP&lt;/td&gt;
&lt;td&gt;Standard pages with headers&lt;/td&gt;
&lt;td&gt;$0.0003&lt;/td&gt;
&lt;td&gt;$0.30&lt;/td&gt;
&lt;td&gt;3,333&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T3 — Stealth&lt;/td&gt;
&lt;td&gt;Protected pages, anti‑bot active&lt;/td&gt;
&lt;td&gt;$0.002&lt;/td&gt;
&lt;td&gt;$2.00&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T4 — Browser&lt;/td&gt;
&lt;td&gt;Full JS rendering required&lt;/td&gt;
&lt;td&gt;$0.004&lt;/td&gt;
&lt;td&gt;$4.00&lt;/td&gt;
&lt;td&gt;250&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T5 — CAPTCHA&lt;/td&gt;
&lt;td&gt;CAPTCHA solving + JS rendering&lt;/td&gt;
&lt;td&gt;$0.02&lt;/td&gt;
&lt;td&gt;$20.00&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Stack Overflow’s dynamic nature typically requires T3 or higher. AlterLab auto‑escalates tiers automatically; you only pay for the tier that succeeds. See the full AlterLab pricing details at /pricing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices
&lt;/h2&gt;

&lt;p&gt;Respect robots.txt and any posted usage limits. Limit request frequency to avoid triggering rate‑limit defenses. When targeting pages with heavy query load, start at T1 and let the system upgrade as needed. Always handle failures gracefully and log response codes for debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling up
&lt;/h2&gt;

&lt;p&gt;For large projects, batch requests using cron schedules or the Scheduler feature. Store results in a durable bucket and process them in parallel workers. Monitor success rates and adjust min_tier settings to control costs while maintaining reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use the AlterLab API for reliable access to public Stack Overflow data.
&lt;/li&gt;
&lt;li&gt;Choose a tier that matches the page’s rendering needs; the system upgrades automatically.
&lt;/li&gt;
&lt;li&gt;Extract structured JSON with Cortex to avoid manual parsing.
&lt;/li&gt;
&lt;li&gt;Keep requests polite, stay within rate limits, and review the site’s Terms of Service.
&lt;/li&gt;
&lt;li&gt;Consult the related guide at /scrape/stack-overflow for deeper examples and patterns.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>javascript</category>
      <category>node</category>
      <category>webscraping</category>
    </item>
    <item>
      <title>How to Give Your AI Agent Access to PubMed Data</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Sun, 05 Jul 2026 13:23:44 +0000</pubDate>
      <link>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-pubmed-data-37f1</link>
      <guid>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-pubmed-data-37f1</guid>
      <description>&lt;h1&gt;
  
  
  How to Give Your AI Agent Access to PubMed Data
&lt;/h1&gt;

&lt;p&gt;TL;DR: Equip your AI agent with structured PubMed data by using AlterLab's Extract API to bypass anti-bot measures and return clean JSON. This enables reliable medical research monitoring, clinical trial tracking, and biotech intelligence without parsing HTML or managing proxies.&lt;/p&gt;

&lt;p&gt;Disclaimer: This guide covers accessing publicly available data. Always review a site's robots.txt and Terms of Service before automated access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI agents need PubMed data
&lt;/h2&gt;

&lt;p&gt;AI agents in healthcare and life sciences require current PubMed data for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Medical research monitoring: Tracking new publications on specific diseases or treatments to update knowledge bases.&lt;/li&gt;
&lt;li&gt;Clinical trial tracking: Identifying emerging trial results or protocol changes for real-time intelligence.&lt;/li&gt;
&lt;li&gt;Biotech intelligence: Monitoring competitor research, grant publications, and emerging science for strategic decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why raw HTTP requests fail for agents
&lt;/h2&gt;

&lt;p&gt;Direct requests to PubMed often fail for agents due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rate limiting: PubMed blocks IPs exceeding request thresholds, causing failed tool calls.&lt;/li&gt;
&lt;li&gt;JavaScript rendering: Dynamic content (like abstracts loaded via JS) returns incomplete HTML to naive scrapers.&lt;/li&gt;
&lt;li&gt;Bot detection: Advanced anti-bot systems challenge requests with CAPTCHAs, wasting agent context windows on retries.&lt;/li&gt;
&lt;li&gt;Token budget waste: Failed requests consume LLM tokens without yielding usable data, increasing costs and reducing pipeline reliability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Connecting your agent to PubMed via AlterLab
&lt;/h2&gt;

&lt;p&gt;Use AlterLab's Extract API (&lt;a href="https://dev.to/docs/extract"&gt;Extract API docs&lt;/a&gt;) to get structured data from PubMed pages. This handles anti-bot bypass, JavaScript rendering, and returns clean JSON ready for your LLM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/docs/quickstart/installation"&gt;Getting started guide&lt;/a&gt; shows how to install the AlterLab SDK. Here’s a Python example extracting structured data from a PubMed article:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="pubmed_extract_agent.py" {3-8}&lt;/p&gt;

&lt;p&gt;from alterlab import Client&lt;/p&gt;

&lt;p&gt;client = Client("YOUR_API_KEY")&lt;/p&gt;

&lt;h1&gt;
  
  
  Define schema for PubMed article structure
&lt;/h1&gt;

&lt;p&gt;schema = {&lt;br&gt;
    "title": "string",&lt;br&gt;
    "authors": "string",&lt;br&gt;
    "journal": "string",&lt;br&gt;
    "pub_date": "string",&lt;br&gt;
    "abstract": "string",&lt;br&gt;
    "doi": "string"&lt;br&gt;
}&lt;/p&gt;
&lt;h1&gt;
  
  
  Extract structured data from a PubMed article URL
&lt;/h1&gt;

&lt;p&gt;result = client.extract(&lt;br&gt;
    url="&lt;a href="https://pubmed.ncbi.nlm.nih.gov/34567890/" rel="noopener noreferrer"&gt;https://pubmed.ncbi.nlm.nih.gov/34567890/&lt;/a&gt;",&lt;br&gt;
    schema=schema&lt;br&gt;
)&lt;/p&gt;
&lt;h1&gt;
  
  
  Result.data is a dict, ready for LLM context or RAG pipeline
&lt;/h1&gt;

&lt;p&gt;print(result.data)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Equivalent cURL command:



```bash title="Terminal" {2-6}
curl -X POST https://api.alterlab.io/api/v1/extract \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://pubmed.ncbi.nlm.nih.gov/34567890/",
    "schema": {
      "title": "string",
      "authors": "string",
      "journal": "string",
      "pub_date": "string",
      "abstract": "string",
      "doi": "string"
    }
  }'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For raw HTML (e.g., if you need full page content), use the Scrape API (/api/v1/scrape). However, structured extraction via Extract API is recommended for agents to minimize post-processing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using the Search API for PubMed queries
&lt;/h2&gt;

&lt;p&gt;To search PubMed for articles matching a query, use AlterLab's Search API (/api/v1/search). This returns structured search results without needing to parse PubMed's search page.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="pubmed_search_agent.py" {3-8}&lt;/p&gt;

&lt;p&gt;from alterlab import Client&lt;/p&gt;

&lt;p&gt;client = Client("YOUR_API_KEY")&lt;/p&gt;

&lt;h1&gt;
  
  
  Search PubMed for recent articles on cancer immunotherapy
&lt;/h1&gt;

&lt;p&gt;search_params = {&lt;br&gt;
    "query": "cancer immunotherapy 2024",&lt;br&gt;
    "site": "pubmed.ncbi.nlm.nih.gov",&lt;br&gt;
    "num_results": 10&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;response = client.search(**search_params)&lt;/p&gt;

&lt;h1&gt;
  
  
  Response contains structured list of articles
&lt;/h1&gt;

&lt;p&gt;for article in response.data:&lt;br&gt;
    print(f"{article['title']} - {article['journal']}")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;




```bash title="Terminal" {2-7}
curl -X POST https://api.alterlab.io/api/v1/search \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "cancer immunotherapy 2024",
    "site": "pubmed.ncbi.nlm.nih.gov",
    "num_results": 10
  }'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  MCP integration
&lt;/h2&gt;

&lt;p&gt;AlterLab provides an MCP server that lets Claude, GPT, or Cursor agents call web data extraction as a native tool. This simplifies agent configuration by abstracting API keys and request handling.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://alterlab.io/docs/tutorials/ai-agent" rel="noopener noreferrer"&gt;AI agent tutorial&lt;/a&gt; to set up the MCP server and integrate it with your agent framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a medical research monitoring pipeline
&lt;/h2&gt;

&lt;p&gt;Here’s an end-to-end example of an agent monitoring PubMed for new diabetes research:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Agent triggers a daily search for "type 2 diabetes treatment 2024" via AlterLab's Search API.&lt;/li&gt;
&lt;li&gt;For each new article (comparing against a known ID set), the agent extracts structured data (title, abstract, DOI) using the Extract API.&lt;/li&gt;
&lt;li&gt;The agent summarizes key findings and updates a medical knowledge base in vector store for RAG.&lt;/li&gt;
&lt;li&gt;If high-impact findings are detected (e.g., new mechanism), the agent alerts researchers via Slack.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;```python title="diabetes_monitoring_pipeline.py" {5-15}&lt;/p&gt;

&lt;p&gt;from alterlab import Client&lt;/p&gt;

&lt;p&gt;from datetime import datetime, timedelta&lt;/p&gt;

&lt;h1&gt;
  
  
  Initialize client (in production, load API key from secure vault)
&lt;/h1&gt;

&lt;p&gt;client = Client("YOUR_API_KEY")&lt;/p&gt;

&lt;h1&gt;
  
  
  Track seen articles to avoid duplicates
&lt;/h1&gt;

&lt;p&gt;SEEN_ARTICLES_FILE = "seen_articles.json"&lt;/p&gt;

&lt;p&gt;def load_seen_articles():&lt;br&gt;
    try:&lt;br&gt;
        with open(SEEN_ARTICLES_FILE) as f:&lt;br&gt;
            return set(json.load(f))&lt;br&gt;
    except FileNotFoundError:&lt;br&gt;
        return set()&lt;/p&gt;

&lt;p&gt;def save_seen_articles(seen_set):&lt;br&gt;
    with open(SEEN_ARTICLES_FILE, "w") as f:&lt;br&gt;
        json.dump(list(seen_set), f)&lt;/p&gt;

&lt;p&gt;def monitor_diabetes_research():&lt;br&gt;
    seen = load_seen_articles()&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Search for new diabetes articles from last 7 days
seven_days_ago = (datetime.now() - timedelta(days=7)).strftime("%Y/%m/%d")
search_query = f"type 2 diabetes treatment {seven_days_ago}[Date - Publication] : 3000[Date - Publication]"

search_response = client.search(
    query=search_query,
    site="pubmed.ncbi.nlm.nih.gov",
    num_results=20
)

new_articles = []
for article in search_response.data:
    # Create unique ID from PMID or DOI
    article_id = article.get("pmid") or article.get("doi") or hashlib.md5(article["title"].encode()).hexdigest()

    if article_id not in seen:
        seen.add(article_id)

        # Extract full structured data for new article
        extract_result = client.extract(
            url=article["url"],
            schema={
                "title": "string",
                "authors": "string",
                "journal": "string",
                "pub_date": "string",
                "abstract": "string",
                "doi": "string"
            }
        )

        new_articles.append(extract_result.data)

# Update knowledge base with new articles (pseudo-code)
if new_articles:
    update_knowledge_base(new_articles)
    save_seen_articles(seen)
    print(f"Added {len(new_articles)} new diabetes research articles to knowledge base")
else:
    print("No new articles found")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;def update_knowledge_base(articles):&lt;br&gt;
    # In practice: embed abstracts and store in vector DB (e.g., Pinecone, Weaviate)&lt;br&gt;
    pass&lt;/p&gt;

&lt;p&gt;if &lt;strong&gt;name&lt;/strong&gt; == "&lt;strong&gt;main&lt;/strong&gt;":&lt;br&gt;
    monitor_diabetes_research()&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Key takeaways

- AI agents need reliable, structured web data to function effectively in knowledge-intensive domains like healthcare.
- AlterLab eliminates anti-bot, rendering, and parsing complexity, letting agents focus on data utilization rather than data acquisition.
- Structured extraction via Extract API delivers PubMed data in LLM-ready JSON, preserving token budgets for reasoning.
- Always comply with robots.txt and rate limits; users bear responsibility for reviewing PubMed's Terms of Service.
- Scale agentic workloads efficiently with usage-based pricing—see [pricing](/pricing) for details.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>aiagents</category>
      <category>llm</category>
      <category>rag</category>
      <category>dataextraction</category>
    </item>
    <item>
      <title>How to Give Your AI Agent Access to arXiv Data</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Sat, 04 Jul 2026 12:36:09 +0000</pubDate>
      <link>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-arxiv-data-4iac</link>
      <guid>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-arxiv-data-4iac</guid>
      <description>&lt;h1&gt;
  
  
  How to Give Your AI Agent Access to arXiv Data
&lt;/h1&gt;

&lt;p&gt;This guide covers accessing publicly available data. Always review a site's robots.txt and Terms of Service before automated access.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Give your AI agent reliable access to arXiv data by using AlterLab's Extract API for structured paper metadata or Search API for query-based retrieval. This avoids rate limits, CAPTCHAs, and HTML parsing overhead while delivering clean JSON directly to your LLM context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI agents need arXiv data
&lt;/h2&gt;

&lt;p&gt;AI agents require arXiv data for three core agentic workflows: monitoring new publications in specific ML domains for RAG knowledge base updates, tracking citation networks to assess paper impact automatically, and building ML paper pipelines that trigger retraining when novel architectures appear. These use cases demand timely, structured access without manual intervention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why raw HTTP requests fail for agents
&lt;/h2&gt;

&lt;p&gt;Direct requests to arxiv.org fail agent pipelines due to rate limiting (60 seconds/minute per IP), JavaScript-dependent content rendering that breaks simple parsers, and bot detection mechanisms triggering CAPTCHAs. Failed requests waste LLM token budgets on retries and error handling, increasing costs by 3-5x while reducing pipeline reliability below 70% success rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting your agent to arXiv via AlterLab
&lt;/h2&gt;

&lt;p&gt;AlterLab's Extract API (/api/v1/extract) returns structured arXiv data ready for LLM consumption. For raw HTML needs, use the Scrape API (/api/v1/scrape). Both handle anti-bot challenges automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structured extraction example
&lt;/h3&gt;

&lt;p&gt;Extract paper metadata without parsing HTML:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="agent_arxiv-org.py" {3-8}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;/p&gt;

&lt;h1&gt;
  
  
  Get structured data for a specific arXiv page
&lt;/h1&gt;

&lt;p&gt;result = client.extract(&lt;br&gt;
    url="&lt;a href="https://arxiv.org/abs/2301.00001" rel="noopener noreferrer"&gt;https://arxiv.org/abs/2301.00001&lt;/a&gt;",&lt;br&gt;
    schema={&lt;br&gt;
        "title": "string",&lt;br&gt;
        "authors": "array",&lt;br&gt;
        "abstract": "string",&lt;br&gt;
        "categories": "array",&lt;br&gt;
        "submitted_date": "string"&lt;br&gt;
    }&lt;br&gt;
)&lt;/p&gt;
&lt;h1&gt;
  
  
  Feed clean data directly to your LLM
&lt;/h1&gt;

&lt;p&gt;print(result.data)&lt;/p&gt;
&lt;h1&gt;
  
  
  Output: {"title": "Attention Is All You Need", ...}
&lt;/h1&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;



```bash title="Terminal"
curl -X POST https://api.alterlab.io/api/v1/extract \
  -H "X-API-Key: YOUR_KEY" \
  -d '{
    "url": "https://arxiv.org/abs/2301.00001",
    "schema": {
      "title": "string",
      "authors": "array",
      "abstract": "string",
      "categories": "array",
      "submitted_date": "string"
    }
  }'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Raw HTML example (when needed)
&lt;/h3&gt;



&lt;p&gt;```python title="scrape_arxiv-org.py" {3-6}&lt;br&gt;
result = client.scrape(&lt;br&gt;
    url="&lt;a href="https://arxiv.org/list/cs.LV/recent" rel="noopener noreferrer"&gt;https://arxiv.org/list/cs.LV/recent&lt;/a&gt;",&lt;br&gt;
    formats=["html"]  # Get clean HTML without JS challenges&lt;br&gt;
)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;



```bash title="Terminal"
curl -X POST https://api.alterlab.io/api/v1/scrape \
  -H "X-API-Key: YOUR_KEY" \
  -d '{"url": "https://arxiv.org/list/cs.LV/recent", "formats": ["html"]}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;See &lt;a href="https://dev.to/docs/extract"&gt;Extract API docs&lt;/a&gt; for full schema options.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using the Search API for arXiv queries
&lt;/h2&gt;

&lt;p&gt;For dynamic paper discovery, AlterLab's Search API (/api/v1/search) queries arXiv through AlterLab's infrastructure:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="search_arxiv-org.py" {3-7}&lt;br&gt;
results = client.search(&lt;br&gt;
    query="large language model transformer",&lt;br&gt;
    site="arxiv.org",&lt;br&gt;
    num_results=10&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;for paper in results.data:&lt;br&gt;
    # Process structured search results&lt;br&gt;
    print(f"{paper['title']} by {paper['authors'][0]}")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;



```bash title="Terminal"
curl -X POST https://api.alterlab.io/api/v1/search \
  -H "X-API-Key: YOUR_KEY" \
  -d '{
    "query": "large language model transformer",
    "site": "arxiv.org",
    "num_results": 10
  }'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This bypasses arXiv's native search limitations while respecting their usage policies.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP integration
&lt;/h2&gt;

&lt;p&gt;AlterLab provides an MCP server that exposes web data capabilities as tools for Claude, GPT, and Cursor agents. Install it to let your agent call &lt;code&gt;alterlab_extract&lt;/code&gt; or &lt;code&gt;alterlab_search&lt;/code&gt; as native functions. See the &lt;a href="https://alterlab.io/docs/tutorials/ai-agent" rel="noopener noreferrer"&gt;AlterLab for AI Agents&lt;/a&gt; tutorial for setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a research paper monitoring pipeline
&lt;/h2&gt;

&lt;p&gt;Here's a complete agentic pipeline for tracking new diffusion model papers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Agent triggers search&lt;/strong&gt;: LLM agent calls AlterLab Search API for &lt;code&gt;query="diffusion model" AND date:[now-7d TO now]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AlterLab returns structured data&lt;/strong&gt;: Clean JSON with paper metadata, no HTML parsing needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent evaluates relevance&lt;/strong&gt;: LLM checks abstracts against research goals&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent extracts full papers&lt;/strong&gt;: For relevant papers, calls Extract API to get structured metadata&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent updates knowledge base&lt;/strong&gt;: Stores embeddings in vector DB for RAG&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent schedules next run&lt;/strong&gt;: Uses cron expression via AlterLab's scheduling feature (set &lt;code&gt;min_tier=3&lt;/code&gt; for JS-heavy pages)
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;```python title="research_pipeline.py" {5-12,18-25}&lt;/p&gt;

&lt;p&gt;from datetime import datetime, timedelta&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;/p&gt;

&lt;p&gt;def monitor_arxiv():&lt;br&gt;
    # Step 1: Search for recent papers&lt;br&gt;
    search_result = client.search(&lt;br&gt;
        query="diffusion model",&lt;br&gt;
        site="arxiv.org",&lt;br&gt;
        num_results=20,&lt;br&gt;
        date_range=f"[(datetime.now() - timedelta(days=7)).isoformat() TO {datetime.now().isoformat()}]"&lt;br&gt;
    )&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Step 2: Process results
relevant_papers = []
for paper in search_result.data:
    # Step 3: LLM relevance check (simplified)
    if "transformer" in paper["abstract"].lower():
        # Step 4: Get full structured data
        full_data = client.extract(
            url=paper["link"],
            schema={"title": "string", "authors": "array", "categories": "array"}
        )
        relevant_papers.append(full_data.data)

# Step 5: Update knowledge base (pseudo-code)
if relevant_papers:
    update_vector_db(relevant_papers)

return len(relevant_papers)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Step 6: Schedule via AlterLab (would be configured in dashboard)
&lt;/h1&gt;
&lt;h1&gt;
  
  
  cron: "0 9 * * *"  # Daily at 9 AM
&lt;/h1&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Key takeaways
- AI agents need reliable, structured arXiv data for research pipelines and RAG
- Direct HTTP requests fail due to anti-bot measures, wasting agent resources
- AlterLab's APIs handle extraction, search, and anti-bot challenges automatically
- Structured output eliminates HTML parsing, saving LLM tokens and reducing latency
- MCP integration lets agents call web data as native tools in Claude/GPT/Cursor
- Always comply with robots.txt and ToS when building agentic data pipelines

&amp;lt;div data-infographic="stats"&amp;gt;
  &amp;lt;div data-stat data-value="99.2%" data-label="Request Success Rate"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-stat data-value="&amp;lt;1s" data-label="Avg Structured Response"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-stat data-value="0" data-label="HTML Parsing Required"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div data-infographic="steps"&amp;gt;
  &amp;lt;div data-step data-number="1" data-title="Agent requests data" data-description="LLM agent calls AlterLab tool with target URL"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="2" data-title="AlterLab fetches + extracts" data-description="Handles anti-bot, returns structured JSON"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="3" data-title="Agent uses clean data" data-description="No parsing, no retries — data goes straight to LLM context"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div data-infographic="try-it" data-url="https://arxiv.org/list/cs.LV/recent" data-description="Extract structured arXiv data for your AI agent"&amp;gt;&amp;lt;/div&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>antibot</category>
      <category>aiagents</category>
      <category>llm</category>
      <category>rag</category>
    </item>
    <item>
      <title>How to Give Your AI Agent Access to CNBC Data</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Sat, 04 Jul 2026 12:21:10 +0000</pubDate>
      <link>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-cnbc-data-3ica</link>
      <guid>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-cnbc-data-3ica</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;To give an AI agent access to CNBC data, call AlterLab’s Extract API with a target URL and a schema. You receive clean JSON ready for your LLM’s context window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI agents need CNBC data
&lt;/h2&gt;

&lt;p&gt;Financial news drives market signals.&lt;br&gt;&lt;br&gt;
Agents use it for earnings alerts.&lt;br&gt;&lt;br&gt;
Pipelines ingest headlines for RAG retrieval.&lt;br&gt;&lt;br&gt;
A single structured article can power multiple downstream decisions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why raw HTTP requests fail for agents
&lt;/h2&gt;

&lt;p&gt;Direct GET requests hit Cloudflare challenges.&lt;br&gt;&lt;br&gt;
JavaScript rendering wastes token budget.&lt;br&gt;&lt;br&gt;
Agents see repeated 429 responses.&lt;br&gt;&lt;br&gt;
Each retry consumes compute and delays the pipeline.&lt;/p&gt;
&lt;h2&gt;
  
  
  Connecting your agent to CNBC via AlterLab
&lt;/h2&gt;

&lt;p&gt;Use the Extract API to get structured output.&lt;br&gt;&lt;br&gt;
No HTML parsing required.&lt;br&gt;&lt;br&gt;
Set a schema that matches the fields you need.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="agent_cnbc-com.py" {3-5}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;/p&gt;

&lt;h1&gt;
  
  
  Structured extraction — get clean data without parsing HTML
&lt;/h1&gt;

&lt;p&gt;result = client.extract(&lt;br&gt;
    url="&lt;a href="https://cnbc.com/example-page" rel="noopener noreferrer"&gt;https://cnbc.com/example-page&lt;/a&gt;",&lt;br&gt;
    schema={"title": "string", "price": "string", "description": "string"}&lt;br&gt;
)&lt;br&gt;
print(result.data)  # Clean structured dict, ready for your LLM&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;




```bash title="Terminal" {2-4}
curl -X POST https://api.alterlab.io/api/v1/extract \
  -H "X-API-Key: YOUR_KEY" \
  -d '{"url": "https://cnbc.com/example-page", "schema": {"title": "string", "price": "string"}}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The platform handles anti‑bot protection behind the scenes.&lt;br&gt;&lt;br&gt;
You only pay for successful extractions.&lt;br&gt;&lt;br&gt;
No need to manage CAPTCHAs or rotating proxies yourself.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using the Search API for CNBC queries
&lt;/h2&gt;

&lt;p&gt;Search lets you discover articles by keyword.&lt;br&gt;&lt;br&gt;
It returns a list of URLs with metadata.&lt;br&gt;&lt;br&gt;
Pick the most relevant link and feed it to Extract.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```bash title="Terminal" {2-5}&lt;br&gt;
curl -X GET &lt;a href="https://api.alterlab.io/api/v1/search" rel="noopener noreferrer"&gt;https://api.alterlab.io/api/v1/search&lt;/a&gt; \&lt;br&gt;
  -H "X-API-Key: YOUR_KEY" \&lt;br&gt;
  -d '{"query": "quarterly earnings cnbc"}'&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


The response includes a `results` array.  
Each entry has a `url` field you can pass to `/extract`.

## MCP integration
Add AlterLab as a tool in your agent’s MCP server.  
Your LLM can call `alterlab_extract` without writing HTTP code.  
See the full guide at [AlterLab for AI Agents](https://alterlab.io/docs/tutorials/ai-agent).

## Building a financial news pipelines pipeline
An end‑to‑end flow looks like this:

1. Agent requests CNBC data via MCP.  
2. AlterLab fetches the page and returns structured JSON.  
3. The LLM consumes the JSON in its context window.  
4. The LLM generates a market summary.

&amp;lt;div data-infographic="stats"&amp;gt;
  &amp;lt;div data-stat data-value="99.2%" data-label="Request Success Rate"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-stat data-value="&amp;lt;1s" data-label="Avg Structured Response"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-stat data-value="0" data-label="HTML Parsing Required"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div data-infographic="steps"&amp;gt;
  &amp;lt;div data-step data-number="1" data-title="Agent requests data" data-description="LLM agent calls AlterLab tool with target URL"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="2" data-title="AlterLab fetches + extracts" data-description="Handles anti‑bot, returns structured JSON"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="3" data-title="Agent uses clean data" data-description="No parsing, no retries — data goes straight to LLM context"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div data-infographic="try-it" data-url="https://cnbc.com" data-description="Extract structured CNBC data for your AI agent"&amp;gt;&amp;lt;/div&amp;gt;

A typical code snippet for the pipeline:



```python title="pipeline_cnbc.py" {4-8}
from alterlab import Client

client = Client("YOUR_API_KEY")

# Step 1: Search for relevant article
search_res = client.search(query="cnbc market recap")
url = search_res.results[0].url

# Step 2: Extract structured data
data = client.extract(url=url, schema={"title":"string", "summary":"string", "sentiment":"string"})
summary = data.data["summary"]

# Step 3: Feed to LLM
# llm.generate(prompt=f"Write a 2‑sentence market outlook using: {summary}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern scales to dozens of articles per hour.&lt;br&gt;&lt;br&gt;
Your agents stay fast and reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use Extract API for clean, structured CNBC output.
&lt;/li&gt;
&lt;li&gt;Avoid raw HTML parsing; let AlterLab handle anti‑bot.
&lt;/li&gt;
&lt;li&gt;Combine Search and Extract for targeted data retrieval.
&lt;/li&gt;
&lt;li&gt;Integrate via MCP for zero‑code tool calls.
&lt;/li&gt;
&lt;li&gt;Monitor cost with AlterLab pricing as your pipeline grows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Always review a site's robots.txt and Terms of Service before automated access. This guide covers accessing publicly available data.&lt;/p&gt;

</description>
      <category>ratelimiting</category>
      <category>mcp</category>
      <category>aiagents</category>
      <category>dataextraction</category>
    </item>
    <item>
      <title>How to Give Your AI Agent Access to Reuters Data</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Fri, 03 Jul 2026 12:11:08 +0000</pubDate>
      <link>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-reuters-data-3fo5</link>
      <guid>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-reuters-data-3fo5</guid>
      <description>&lt;h1&gt;
  
  
  How to Give Your AI Agent Access to Reuters Data
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; To give an AI agent access to Reuters data, use AlterLab's Extract API to transform raw news pages into structured JSON. This bypasses JavaScript rendering and anti-bot protections, providing your LLM with clean data that fits directly into its context window.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: This guide covers accessing publicly available data. Always review a site's robots.txt and Terms of Service before automated access.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why AI agents need Reuters data
&lt;/h2&gt;

&lt;p&gt;For an AI agent to be effective in financial or geopolitical intelligence, it cannot rely solely on its training data. Training data is static; real-world markets and political landscapes move in real-time. To build high-utility agentic workflows, you must connect them to live news sources like Reuters.&lt;/p&gt;

&lt;p&gt;Common agentic use cases include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;News Monitoring Pipelines&lt;/strong&gt;: Agents that monitor specific keywords (e.1., "Federal Reserve" or "semiconductor supply chain") and trigger workflows when significant news breaks.&lt;/li&gt;
&lt;li&gt; &lt;a href="https://alterlab.io/docs/tutorials/ai-agent" rel="noopener noreferrer"&gt;RAG-enhanced Intelligence&lt;/a&gt;: Providing an LLM with the most recent news as context to prevent hallucinations and ensure responses are grounded in current events.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Event Detection &amp;amp; Signal Tracking&lt;/strong&gt;: Using agents to parse news sentiment or supply chain disruptions to trigger automated actions in trading or logistics systems.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why raw HTTP requests fail for agents
&lt;/h2&gt;

&lt;p&gt;If you attempt to build a tool-calling loop where an agent uses a standard &lt;code&gt;requests&lt;/code&gt; or &lt;code&gt;fetch&lt;/code&gt; call to reach Reuters, your pipeline will fail almost immediately. Modern news sites employ sophisticated edge protections to prevent scraping.&lt;/p&gt;

&lt;p&gt;Common failure points include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;JavaScript Rendering&lt;/strong&gt;: Much of the content on Reuters is hydrated via client-side JavaScript. A basic HTTP GET request returns a nearly empty HTML shell.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://alterlab.io/docs/quickstart/installation" rel="noopener noreferrer"&gt;Bot Detection&lt;/a&gt;: Servers identify the lack of browser fingerprints, leading to 403 Forbidden errors or endless CAPTCHAs.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Rate Limiting&lt;/strong&gt;: Without rotating residential proxies, your agent's IP will be flagged after a few requests.&lt;/li&gt;
&lt;li&gt;  &lt;a href="/pricing"&gt;Token Budget Waste&lt;/a&gt;: Even if you successfully fetch a page, sending raw, uncleaned HTML to an LLM is expensive and fills the context window with noise (scripts, nav bars, ads) instead of signal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Connecting your agent to Reuters via AlterLab
&lt;/h2&gt;

&lt;p&gt;Instead of building a browser-based scraping-engine, you should treat data acquisition as a structured tool call. AlterLab provides two primary methods for this: the Scrape API for raw data and the Extract API for structured intelligence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 1: Extracting structured news via Extract API
&lt;/h3&gt;

&lt;p&gt;For most agentic workflows, you don't want HTML. You want a JSON object containing the headline, the body text, and the publication timestamp. This minimizes token usage and maximizes reasoning accuracy.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="reuters_extractor.py" {2-8}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;/p&gt;

&lt;h1&gt;
  
  
  Extract clean news data without writing a single CSS selector
&lt;/h1&gt;

&lt;p&gt;result = client.extract(&lt;br&gt;
    url="&lt;a href="https://www.reuters.com/business/finance-industry/example-news-article/" rel="noopener noreferrer"&gt;https://www.reuters.com/business/finance-industry/example-news-article/&lt;/a&gt;",&lt;br&gt;
    schema={&lt;br&gt;
        "headline": "string",&lt;br&gt;
        "body": "string",&lt;br&gt;
        "timestamp": "string",&lt;br&gt;
        "author": "string"&lt;br&gt;
    }&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;print(result.data) # Returns a clean dictionary for your LLM&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Using the cURL equivalent for testing your tool definitions:



```bash title="Terminal"
curl -X POST https://api.alterlab.io/api/v1/extract \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://reuters.com/...",
    "schema": {
      "headline": "string",
      "body": "string"
    }
  }'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For more advanced schema definitions, refer to our &lt;a href="/docs/extract"&gt;Extract API docs&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Method 2: Broad search via the Search API
&lt;/h3&gt;

&lt;p&gt;If your agent needs to &lt;em&gt;find&lt;/em&gt; news rather than process a known URL, use the Search API. This allows the agent to perform a query and receive a list of relevant URLs or snippets.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="agent_search.py" {4-7}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;/p&gt;

&lt;h1&gt;
  
  
  The agent performs a search to find recent context
&lt;/h1&gt;

&lt;p&gt;search_results = client.search(&lt;br&gt;
    query="impact of interest rates on tech stocks",&lt;br&gt;
    site_limit_only="reuters.com"&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;for article in search_results.items:&lt;br&gt;
    print(f"Found: {article.title} at {article.url}")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Using MCP for seamless integration

If you are building custom agents using Model Context Protocol (MCP), you can integrate AlterLab as a dedicated tool. This allows Claude or other LLM-based agents to fetch Reuters data directly within their reasoning loop without extra boilerplate code. By exposing AlterLab as an MCP server, your agent gains a "web-search" capability that returns structured,-ready data instead of messy HTML.

&amp;lt;div data/instruction="link_to_tutorial"&amp;gt;
Learn how to implement this in our &amp;lt;a href="https://alterlab.io/docs/tutorials/ai-agent"&amp;gt;AI Agent Guide&amp;lt;/a&amp;gt;.
&amp;lt;/div&amp;gt;

## Building a news monitoring pipeline

A production-grade agentic pipeline follows a specific flow: the agent identifies a need for data, triggers a tool call, receives structured JSON, and then performs reasoning.

&amp;lt;div data-infographic="steps"&amp;gt;
  &amp;lt;div data-step data-number="1" data-title="Agent requests data" data-description="LLM agent calls AlterLab tool with target URL or search term"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="2" data-title="AlterLab fetches + extracts" data-description="Handles TLS fingerprints, JS rendering, and returns JSON"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div data-step data-number="3" data_description="Agent uses clean data" data-description="No parsing, no retries — data goes straight to LLM context"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

### Full Pipeline Implementation

Here is how a production pipeline looks when an agent is tasked with monitoring a topic:



```python title="news_monitoring_pipeline.py"

from openai import OpenAI # Or any LLM provider

# Initialize clients
llm = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
data_client = alterlab.Client(api_key=os.environ["ALTERLAB_API_KEY"])

def news_monitoring_agent(topic: str):
    # Step 1: Search for news via AlterLab
    print(f"Searching for: {topic}")
    search_results = data_client.search(query=f"latest news about {topic}", site_limit_only="reuters.com")

    if not search_results.items:
        return "No recent news found."

    # Step 2: Deep dive into the top result
    top_url = search_results.items[0].url
    print(f"Extracting content from: {top_url}")

    content = data_client.extract(
        url=top_url,
        schema={"summary": "string", "sentiment": "string", "key_entities": "list[string]"}
    )

    # Step 3: LLM Reasoning
    prompt = f"Based on this news: {content.data['summary']}, what is the sentiment toward {topic}? Entities: {content.data['key_entities']}"

    response = llm.chat.complet_messages(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}]
    )

    return response.choices[0].message.content

# Execute the agentic loop
print(news_monitoring_agent("NVIDIA earnings"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Don's scrape, extract&lt;/strong&gt;: Don't try to parse HTML with regex or BeautifulSoup. Use the Extract API to get clean JSON that fits your agent's schema.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Handle the heavy lifting&lt;/strong&gt;: Let the API manage JavaScript rendering,-proxy rotation, and anti-bot measures so your agent can focus on reasoning.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Optimize for context&lt;/strong&gt;: Delivering raw HTML to an LLM is a waste of money. Always transform web data into minimal, high-signal structured formats.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hit reply if you have questions.&lt;/p&gt;

&lt;p&gt;AlterLab // Web Data, Simplified.&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>llm</category>
      <category>rag</category>
      <category>dataextraction</category>
    </item>
    <item>
      <title>How to Give Your AI Agent Access to TechCrunch Data</title>
      <dc:creator>AlterLab</dc:creator>
      <pubDate>Fri, 03 Jul 2026 12:11:07 +0000</pubDate>
      <link>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-techcrunch-data-1naj</link>
      <guid>https://dev.to/alterlab/how-to-give-your-ai-agent-access-to-techcrunch-data-1naj</guid>
      <description>&lt;h1&gt;
  
  
  How to Give Your AI Agent Access to TechCrunch Data
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: This guide covers accessing publicly available data. Always review a site's robots.txt and Terms of Service before automated access.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;To give an AI agent access to TechCrunch data, connect your agent's tool-calling interface to a structured data API. By using the AlterLab Extract API, agents can request a specific URL and receive a JSON object matching a predefined schema, removing the need for the LLM to parse raw HTML or handle bot detection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI agents need TechCrunch data
&lt;/h2&gt;

&lt;p&gt;For AI engineers building agentic systems, live web data is the difference between a static chatbot and a functional autonomous agent. TechCrunch serves as a primary source of truth for the technology sector, making it essential for several agentic workflows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Startup News Monitoring&lt;/strong&gt;&lt;br&gt;
Agents can be programmed to monitor specific categories (e.g., "AI" or "Fintech") to identify emerging players. Instead of a human reading a feed, an agent can filter for specific keywords and summarize the impact of a new product launch in real-time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Funding Round Detection&lt;/strong&gt;&lt;br&gt;
By monitoring the "Startups" section, agents can trigger workflows the moment a funding announcement is published. This allows a pipeline to automatically update a CRM, notify a venture capital team, or trigger a competitive analysis report.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Tech Trend Pipelines&lt;/strong&gt;&lt;br&gt;
RAG (Retrieval-Augmented Generation) pipelines often suffer from "knowledge cutoff." Giving an agent access to TechCrunch allows the LLM to ground its responses in today's news, ensuring that answers about the latest LLM releases or hardware breakthroughs are accurate and current.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why raw HTTP requests fail for agents
&lt;/h2&gt;

&lt;p&gt;Most developers attempt to give their agents web access by providing a simple &lt;code&gt;requests.get()&lt;/code&gt; or &lt;code&gt;axios.get()&lt;/code&gt; tool. In a production agentic pipeline, this approach fails for four specific reasons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rate Limiting and IP Blocking&lt;/strong&gt;&lt;br&gt;
TechCrunch employs sophisticated bot detection. When an agent makes multiple requests in rapid succession to track a trend, the server identifies the non-browser behavior and returns a 403 Forbidden or 429 Too Many Requests error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript Rendering&lt;/strong&gt;&lt;br&gt;
Modern news sites often load content dynamically. A raw HTTP request retrieves the initial HTML shell, but the actual article content or the latest headlines may be injected via JavaScript. Without a headless browser, your agent sees an empty page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Token Budget Waste&lt;/strong&gt;&lt;br&gt;
Feeding raw HTML into an LLM's context window is inefficient. A single TechCrunch page can contain thousands of lines of boilerplate HTML, navigation menus, and tracking scripts. This consumes thousands of tokens, increasing costs and introducing noise that leads to hallucinations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Retry Loop&lt;/strong&gt;&lt;br&gt;
When an agent hits a CAPTCHA or a block, the LLM often attempts to "fix" the problem by retrying the request or changing the URL. This creates an infinite loop that drains your API budget without ever retrieving the data.&lt;/p&gt;


  
  
  

&lt;h2&gt;
  
  
  Connecting your agent to TechCrunch via AlterLab
&lt;/h2&gt;

&lt;p&gt;The most efficient way to integrate this data is by treating the web as a structured database. Instead of asking the agent to "scrape" the page, you provide a tool that "extracts" specific fields.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using the Extract API for Structured Output
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://dev.to/docs/extract"&gt;Extract API docs&lt;/a&gt; describe how to define a schema that the API uses to return only the data your agent needs. This keeps the context window clean and the costs low.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="agent_techcrunch_extract.py" {6-11}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;/p&gt;

&lt;h1&gt;
  
  
  Define the schema to avoid sending raw HTML to the LLM
&lt;/h1&gt;

&lt;p&gt;schema = {&lt;br&gt;
    "article_title": "string",&lt;br&gt;
    "author": "string",&lt;br&gt;
    "funding_amount": "string",&lt;br&gt;
    "company_name": "string"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;result = client.extract(&lt;br&gt;
    url="&lt;a href="https://techcrunch.com/2024/example-funding-story/" rel="noopener noreferrer"&gt;https://techcrunch.com/2024/example-funding-story/&lt;/a&gt;",&lt;br&gt;
    schema=schema&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;print(result.data) &lt;/p&gt;
&lt;h1&gt;
  
  
  Output: {'article_title': 'Company X raises $10M', 'author': 'Jane Doe', ...}
&lt;/h1&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


For those building in Go, Rust, or Node.js, the cURL interface is the fastest way to implement the tool call.



```bash title="Terminal"
curl -X POST https://api.alterlab.io/api/v1/extract \
  -H "X-API-Key: YOUR_KEY" \
  -d '{
    "url": "https://techcrunch.com/2024/example-funding-story/",
    "schema": {
      "article_title": "string",
      "funding_amount": "string"
    }
  }'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Using the Scrape API for Raw Data
&lt;/h3&gt;

&lt;p&gt;If your agent needs to perform its own analysis on the page structure or needs the full text for a complex RAG pipeline, use the &lt;code&gt;/api/v1/scrape&lt;/code&gt; endpoint. This provides the rendered HTML or Markdown.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```python title="agent_techcrunch_scrape.py" {7-9}&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_API_KEY")&lt;/p&gt;

&lt;h1&gt;
  
  
  Requesting markdown format to save tokens in the LLM context window
&lt;/h1&gt;

&lt;p&gt;result = client.scrape(&lt;br&gt;
    url="&lt;a href="https://techcrunch.com" rel="noopener noreferrer"&gt;https://techcrunch.com&lt;/a&gt;",&lt;br&gt;
    formats=["markdown"]&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;print(result.markdown)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


## Using the Search API for TechCrunch queries
An agent cannot always guess the exact URL of a story. To enable discovery, your agent needs a search tool. The `/api/v1/search` endpoint allows the agent to query TechCrunch specifically.

By restricting the search to `site:techcrunch.com`, the agent can find the most relevant URLs to then pass into the Extract API.



```bash title="Terminal"
curl -X POST https://api.alterlab.io/api/v1/search \
  -H "X-API-Key: YOUR_KEY" \
  -d '{"query": "site:techcrunch.com AI agent funding 2024"}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  MCP integration
&lt;/h2&gt;

&lt;p&gt;For developers using Claude, GPT-4, or Cursor, the Model Context Protocol (MCP) is the gold standard for tool integration. AlterLab provides an MCP server that allows these agents to call scraping and extraction tools directly without you writing custom wrapper functions.&lt;/p&gt;

&lt;p&gt;By installing the AlterLab MCP server, your agent gains a native &lt;code&gt;extract_data&lt;/code&gt; tool. When the agent thinks, "I need to check the latest news on TechCrunch," it simply executes the tool call, receives the JSON, and incorporates it into its response.&lt;/p&gt;

&lt;p&gt;For implementation details, see the &lt;a href="https://alterlab.io/docs/tutorials/ai-agent" rel="noopener noreferrer"&gt;AlterLab for AI Agents&lt;/a&gt; guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a startup news monitoring pipeline
&lt;/h2&gt;

&lt;p&gt;Here is a practical end-to-end implementation of a monitoring pipeline. This pipeline follows a logic flow of: &lt;strong&gt;Trigger $\rightarrow$ Search $\rightarrow$ Extract $\rightarrow$ Analyze&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation Example
&lt;/h3&gt;



&lt;p&gt;```python title="funding_pipeline.py" {12-25}&lt;/p&gt;

&lt;p&gt;from openai import OpenAI&lt;/p&gt;

&lt;p&gt;client = alterlab.Client("YOUR_ALTERLAB_KEY")&lt;br&gt;
llm = OpenAI(api_key="YOUR_OPENAI_KEY")&lt;/p&gt;

&lt;p&gt;def monitor_funding():&lt;br&gt;
    # 1. Search for recent funding news&lt;br&gt;
    search_results = client.search(query="site:techcrunch.com 'Series A' AI")&lt;br&gt;
    latest_url = search_results[0]['url']&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 2. Extract structured data from the top result
data = client.extract(
    url=latest_url,
    schema={"company": "string", "amount": "string", "lead_investor": "string"}
)

# 3. Pass structured data to LLM for analysis
prompt = f"Analyze this funding round: {data.data}. Is this a competitor to our product?"
response = llm.chat.completions.create(
    model="gpt-4-turbo",
    messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;print(monitor_funding())&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


To scale this pipeline to monitor hundreds of pages, you can integrate scheduling. Use the [Getting started guide](/docs/quickstart/installation) to set up your environment, then implement cron-based scrapes to ensure your agent's knowledge base is updated every hour.

&amp;lt;div data-infographic="try-it" data-url="https://techcrunch.com" data-description="Extract structured TechCrunch data for your AI agent"&amp;gt;&amp;lt;/div&amp;gt;

## Key takeaways
*   **Avoid raw HTML**: Use structured extraction to save token costs and reduce LLM hallucinations.
*   **Handle anti-bot upstream**: Use an API that handles proxies and rendering so your agent doesn't get stuck in retry loops.
*   **Search first, Extract second**: Combine the Search API with the Extract API to give your agent the ability to discover and then analyze data.
*   **Standardize with MCP**: Use the Model Context Protocol for seamless integration with modern AI IDEs and LLMs.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>aiagents</category>
      <category>llm</category>
      <category>rag</category>
      <category>datapipelines</category>
    </item>
  </channel>
</rss>
