Table of contents

How do I Implement Prompt Engineering for Web Scraping Tasks?

Prompt engineering is the practice of crafting effective instructions for Large Language Models (LLMs) like GPT to extract structured data from web pages. Unlike traditional web scraping that relies on CSS selectors or XPath, prompt engineering enables AI models to understand content contextually and extract information even from complex or inconsistently structured pages.

Understanding Prompt Engineering for Web Scraping

Prompt engineering for web scraping involves designing clear, specific instructions that guide an LLM to identify and extract the exact data you need from HTML content or rendered web pages. The quality of your prompts directly impacts the accuracy, consistency, and reliability of the extracted data.

Why Use Prompt Engineering for Web Scraping?

Traditional web scraping breaks when websites change their structure, but AI-powered scraping can adapt to layout variations by understanding content semantically. This makes prompt engineering particularly valuable for:

  • Dynamic websites with frequently changing layouts
  • Unstructured content without consistent HTML patterns
  • Complex data extraction requiring contextual understanding
  • Multi-language sites where content structure varies by locale
  • Legacy websites with inconsistent markup

Core Principles of Effective Prompts

1. Be Specific and Clear

Vague prompts lead to inconsistent results. Always specify exactly what data you want, its format, and how to handle edge cases.

Poor prompt: Extract product information from this page.

Better prompt: ``` Extract the following product information from this HTML: 1. Product name (string) 2. Price in USD (number, without currency symbol) 3. Availability status (boolean: true if in stock, false otherwise) 4. Product rating (number from 1-5, or null if not available)

Return the data as a JSON object with keys: name, price, in_stock, rating. ```

2. Provide Structure and Format Requirements

Always define the expected output format. JSON is ideal for structured data extraction as it's easily parsable and widely supported.

import openai

prompt = """
Analyze this product page HTML and extract data in the following JSON format:
{
    "title": "product title",
    "price": 0.00,
    "currency": "USD",
    "features": ["feature1", "feature2"],
    "specifications": {
        "brand": "brand name",
        "model": "model number"
    },
    "in_stock": true
}

Only return the JSON object, no additional text.

HTML:
{html_content}
"""

response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=[
        {"role": "system", "content": "You are a web scraping assistant that extracts structured data from HTML."},
        {"role": "user", "content": prompt.format(html_content=html)}
    ],
    temperature=0  # Lower temperature for more consistent outputs
)

data = response.choices[0].message.content

3. Include Examples (Few-Shot Learning)

Providing examples dramatically improves extraction accuracy and consistency. This technique is called few-shot prompting.

const prompt = `
Extract article metadata from the HTML below. Here are examples:

Example 1:
Input HTML: <article><h1>First Article</h1><span class="author">John Doe</span><time>2024-01-15</time></article>
Output: {"title": "First Article", "author": "John Doe", "date": "2024-01-15"}

Example 2:
Input HTML: <div class="post"><h2>Second Post</h2><p class="byline">By Jane Smith</p><p class="published">Jan 20, 2024</p></div>
Output: {"title": "Second Post", "author": "Jane Smith", "date": "2024-01-20"}

Now extract from this HTML:
${htmlContent}

Return only the JSON object.
`;

const response = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`
    },
    body: JSON.stringify({
        model: 'gpt-4',
        messages: [
            {role: 'system', content: 'You are a data extraction specialist.'},
            {role: 'user', content: prompt}
        ],
        temperature: 0
    })
});

Advanced Prompt Engineering Techniques

1. Chain of Thought Prompting

For complex extractions, guide the model through reasoning steps:

prompt = """
Extract pricing information from this e-commerce page. Follow these steps:

1. First, identify all price-related elements (original price, sale price, discounts)
2. Determine which price is currently active
3. Calculate the discount percentage if applicable
4. Check for any additional fees or taxes mentioned
5. Return the final data structure

Expected output format:
{
    "original_price": 0.00,
    "current_price": 0.00,
    "discount_percentage": 0,
    "currency": "USD",
    "additional_fees": []
}

HTML:
{html}
"""

2. Role-Based Prompting

Assign the LLM a specific role to improve context understanding:

system_prompt = """
You are an expert web scraping engineer with 10 years of experience in data extraction.
Your specialty is extracting structured product data from e-commerce websites.
You always return valid JSON and handle edge cases like missing data gracefully.
When data is unavailable, you use null values instead of making assumptions.
"""

user_prompt = """
Extract all product information from this page, including variants, pricing tiers, and specifications.
{html_content}
"""

3. Validation and Error Handling

Include validation rules in your prompts to ensure data quality:

const prompt = `
Extract contact information from this webpage with strict validation:

Rules:
- Email must be a valid email format
- Phone numbers should be in E.164 format (e.g., +1234567890)
- URLs must be complete with protocol (https://)
- If any field cannot be validated, set it to null

Return format:
{
    "email": "valid@email.com" or null,
    "phone": "+1234567890" or null,
    "website": "https://example.com" or null,
    "address": "full address" or null
}

HTML:
${html}
`;

Practical Implementation Example

Here's a complete example combining multiple prompt engineering techniques:

import openai
import json
from typing import Dict, Optional

class AIWebScraper:
    def __init__(self, api_key: str):
        self.client = openai.OpenAI(api_key=api_key)

    def create_extraction_prompt(self, html: str, schema: Dict) -> str:
        """
        Create a structured prompt for data extraction
        """
        prompt = f"""
You are a professional data extraction system. Extract information from the HTML below according to this schema:

{json.dumps(schema, indent=2)}

RULES:
1. Return ONLY valid JSON matching the schema
2. Use null for missing or unavailable data
3. Preserve data types as specified in schema
4. Remove any HTML tags from extracted text
5. Normalize whitespace and trim values

HTML CONTENT:
{html}

OUTPUT (JSON only):
"""
        return prompt

    def extract_data(self, html: str, schema: Dict,
                     examples: Optional[list] = None) -> Dict:
        """
        Extract structured data from HTML using GPT
        """
        messages = [
            {
                "role": "system",
                "content": "You are a precise web scraping assistant that extracts structured data from HTML."
            }
        ]

        # Add few-shot examples if provided
        if examples:
            for example in examples:
                messages.append({
                    "role": "user",
                    "content": f"Extract from: {example['html']}"
                })
                messages.append({
                    "role": "assistant",
                    "content": json.dumps(example['output'])
                })

        # Add the actual extraction request
        messages.append({
            "role": "user",
            "content": self.create_extraction_prompt(html, schema)
        })

        response = self.client.chat.completions.create(
            model="gpt-4-turbo-preview",
            messages=messages,
            temperature=0,
            response_format={"type": "json_object"}
        )

        return json.loads(response.choices[0].message.content)

# Usage example
scraper = AIWebScraper(api_key="your-api-key")

schema = {
    "title": "string",
    "price": "number",
    "rating": "number or null",
    "reviews_count": "integer",
    "in_stock": "boolean"
}

examples = [
    {
        "html": "<div><h1>Product A</h1><span>$29.99</span><div>★★★★★ (150)</div></div>",
        "output": {
            "title": "Product A",
            "price": 29.99,
            "rating": 5.0,
            "reviews_count": 150,
            "in_stock": True
        }
    }
]

result = scraper.extract_data(html_content, schema, examples)
print(json.dumps(result, indent=2))

Optimizing Token Usage and Cost

When implementing AI-powered web scraping, token costs can add up quickly. Here are optimization strategies:

1. Preprocess HTML

Remove unnecessary content before sending to the LLM:

from bs4 import BeautifulSoup

def clean_html_for_llm(html: str) -> str:
    """
    Remove scripts, styles, and unnecessary attributes to reduce tokens
    """
    soup = BeautifulSoup(html, 'html.parser')

    # Remove script and style tags
    for tag in soup(['script', 'style', 'noscript']):
        tag.decompose()

    # Remove comments
    for comment in soup.findAll(text=lambda text: isinstance(text, Comment)):
        comment.extract()

    # Remove unnecessary attributes
    for tag in soup.find_all():
        tag.attrs = {k: v for k, v in tag.attrs.items()
                     if k in ['class', 'id', 'href', 'src']}

    return str(soup)

2. Use Targeted Extraction

Instead of sending entire pages, extract relevant sections first using traditional methods:

def extract_product_section(html: str) -> str:
    """
    Use BeautifulSoup to isolate the product section before LLM processing
    """
    soup = BeautifulSoup(html, 'html.parser')

    # Find the main product container
    product_section = soup.find('div', {'class': 'product-details'}) or \
                     soup.find('div', {'id': 'product'}) or \
                     soup.find('article')

    return str(product_section) if product_section else html

3. Batch Processing

Process multiple similar pages with a single prompt when possible:

batch_prompt = """
Extract product data from these multiple product listings.
Return an array of JSON objects, one for each product.

Product 1 HTML:
{html1}

Product 2 HTML:
{html2}

Product 3 HTML:
{html3}

Return format: [{"title": "...", "price": ...}, ...]
"""

Handling Edge Cases and Errors

Robust prompt engineering accounts for common issues:

advanced_prompt = """
Extract product information with these edge case rules:

1. MISSING DATA: Use null for unavailable fields, never guess
2. MULTIPLE PRICES: If multiple prices exist, use the lowest current price
3. SOLD OUT: Set in_stock to false if you see "sold out", "unavailable", or "out of stock"
4. RATINGS: Accept formats like "4.5/5", "4.5 stars", or "★★★★☆" (convert to numeric)
5. VARIANTS: If multiple product variants exist, extract the default/first variant
6. CURRENCY: Always include currency code (USD, EUR, etc.)

If the page is not a product page or data cannot be reliably extracted, return:
{"error": "Unable to extract product data", "reason": "brief explanation"}

HTML:
{html}
"""

Testing and Iteration

Prompt engineering is iterative. Test your prompts with diverse examples:

def test_prompt(scraper, test_cases):
    """
    Test prompt performance across multiple scenarios
    """
    results = []

    for test_case in test_cases:
        try:
            extracted = scraper.extract_data(
                test_case['html'],
                test_case['schema']
            )

            # Compare with expected output
            accuracy = calculate_accuracy(extracted, test_case['expected'])
            results.append({
                'test_id': test_case['id'],
                'accuracy': accuracy,
                'extracted': extracted
            })
        except Exception as e:
            results.append({
                'test_id': test_case['id'],
                'error': str(e)
            })

    return results

Best Practices Summary

  1. Start simple: Begin with basic extraction and add complexity as needed
  2. Use low temperature: Set temperature to 0 or 0.1 for consistent outputs
  3. Validate outputs: Always parse and validate the JSON response
  4. Include examples: Few-shot learning significantly improves accuracy
  5. Define data types: Specify exact types (string, number, boolean, array)
  6. Handle nulls explicitly: Tell the model how to handle missing data
  7. Preprocess HTML: Clean and minimize HTML before sending to the LLM
  8. Test extensively: Use diverse test cases to validate prompt reliability
  9. Monitor costs: Track token usage and optimize where possible
  10. Iterate based on failures: Analyze extraction errors and refine prompts

Combining Traditional and AI Scraping

For optimal results, consider combining traditional web scraping with LLM-based extraction. Use CSS selectors or XPath to isolate relevant sections, then apply AI for complex data extraction within those sections. This hybrid approach balances cost, speed, and accuracy.

Conclusion

Effective prompt engineering for web scraping requires clarity, structure, and iterative refinement. By following these techniques—providing clear instructions, including examples, defining output formats, and handling edge cases—you can build reliable AI-powered scraping systems that adapt to changing website structures while maintaining data quality.

Understanding how to use ChatGPT for web scraping and applying these prompt engineering principles will help you extract accurate, structured data from even the most challenging websites.

Try WebScraping.AI for Your Web Scraping Needs

Looking for a powerful web scraping solution? WebScraping.AI provides an LLM-powered API that combines Chromium JavaScript rendering with rotating proxies for reliable data extraction.

Key Features:

  • AI-powered extraction: Ask questions about web pages or extract structured data fields
  • JavaScript rendering: Full Chromium browser support for dynamic content
  • Rotating proxies: Datacenter and residential proxies from multiple countries
  • Easy integration: Simple REST API with SDKs for Python, Ruby, PHP, and more
  • Reliable & scalable: Built for developers who need consistent results

Getting Started:

Get page content with AI analysis:

curl "https://api.webscraping.ai/ai/question?url=https://example.com&question=What is the main topic?&api_key=YOUR_API_KEY"

Extract structured data:

curl "https://api.webscraping.ai/ai/fields?url=https://example.com&fields[title]=Page title&fields[price]=Product price&api_key=YOUR_API_KEY"

Try in request builder

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon