> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/D4Vinci/Scrapling/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Start

> Get up and running with Scrapling in minutes

## Prerequisites

Make sure you have Scrapling installed. If not, see the [Installation guide](/installation).

For the examples below, you'll need:

```bash theme={null}
pip install "scrapling[fetchers]"
scrapling install
```

## Your First Scrape

Let's scrape a simple website using HTTP requests:

<Steps>
  <Step title="Import the Fetcher">
    ```python theme={null}
    from scrapling.fetchers import Fetcher
    ```
  </Step>

  <Step title="Fetch the page">
    ```python theme={null}
    page = Fetcher.get('https://quotes.toscrape.com/')
    ```
  </Step>

  <Step title="Extract data with CSS selectors">
    ```python theme={null}
    # Get all quotes
    quotes = page.css('.quote .text::text').getall()
    print(quotes)

    # Get all authors
    authors = page.css('.quote .author::text').getall()
    print(authors)
    ```
  </Step>
</Steps>

<Tip>
  The `::text` pseudo-element extracts text content, similar to Scrapy/Parsel syntax.
</Tip>

## Using Sessions

For multiple requests to the same domain, use sessions to maintain cookies and state:

```python theme={null}
from scrapling.fetchers import FetcherSession

with FetcherSession(impersonate='chrome') as session:
    # First request
    page1 = session.get('https://quotes.toscrape.com/')
    quotes = page1.css('.quote .text::text').getall()
    
    # Follow pagination - cookies maintained
    page2 = session.get('https://quotes.toscrape.com/page/2/')
    more_quotes = page2.css('.quote .text::text').getall()
```

## Stealthy Scraping

For websites with anti-bot protection, use the StealthyFetcher:

<Steps>
  <Step title="Import StealthyFetcher">
    ```python theme={null}
    from scrapling.fetchers import StealthyFetcher
    ```
  </Step>

  <Step title="Fetch protected pages">
    ```python theme={null}
    # Bypass Cloudflare automatically
    page = StealthyFetcher.fetch(
        'https://nopecha.com/demo/cloudflare',
        solve_cloudflare=True,
        headless=True
    )
    ```
  </Step>

  <Step title="Extract data">
    ```python theme={null}
    data = page.css('#padded_content a').getall()
    print(page.status)  # 200
    ```
  </Step>
</Steps>

<CodeGroup>
  ```python Synchronous theme={null}
  from scrapling.fetchers import StealthyFetcher

  page = StealthyFetcher.fetch(
      'https://www.browserscan.net/bot-detection',
      headless=True,
      network_idle=True
  )
  print(f"Status: {page.status}")  # 200
  ```

  ```python Asynchronous theme={null}
  from scrapling.fetchers import StealthyFetcher

  page = await StealthyFetcher.async_fetch(
      'https://www.browserscan.net/bot-detection',
      headless=True,
      network_idle=True
  )
  print(f"Status: {page.status}")  # 200
  ```
</CodeGroup>

## Building a Spider

For larger scraping projects, use Scrapling's spider framework:

<Steps>
  <Step title="Create a spider class">
    ```python theme={null}
    from scrapling.spiders import Spider, Response

    class QuotesSpider(Spider):
        name = "quotes"
        start_urls = ["https://quotes.toscrape.com/"]
        concurrent_requests = 10
    ```
  </Step>

  <Step title="Define the parse method">
    ```python theme={null}
        async def parse(self, response: Response):
            # Extract quotes from current page
            for quote in response.css('.quote'):
                yield {
                    "text": quote.css('.text::text').get(),
                    "author": quote.css('.author::text').get(),
                    "tags": quote.css('.tag::text').getall(),
                }
            
            # Follow pagination
            next_page = response.css('.next a::attr(href)').get()
            if next_page:
                yield response.follow(next_page)
    ```
  </Step>

  <Step title="Run the spider">
    ```python theme={null}
    # Run and get results
    result = QuotesSpider().start()

    print(f"Scraped {len(result.items)} quotes")

    # Export to JSON
    result.items.to_json("quotes.json")

    # Or JSONL
    result.items.to_jsonl("quotes.jsonl")
    ```
  </Step>
</Steps>

### Complete Spider Example

```python theme={null}
from scrapling.spiders import Spider, Response

class QuotesSpider(Spider):
    name = "quotes"
    start_urls = ["https://quotes.toscrape.com/"]
    concurrent_requests = 10
    
    async def parse(self, response: Response):
        for quote in response.css('.quote'):
            yield {
                "text": quote.css('.text::text').get(),
                "author": quote.css('.author::text').get(),
                "tags": quote.css('.tag::text').getall(),
            }
        
        next_page = response.css('.next a::attr(href)').get()
        if next_page:
            yield response.follow(next_page)

# Run the spider
result = QuotesSpider().start()
print(f"Scraped {len(result.items)} quotes")
result.items.to_json("quotes.json")
```

<Note>
  Spiders support pause/resume, multiple session types, proxy rotation, and streaming mode. See [Spider Documentation](/spiders/getting-started) for advanced features.
</Note>

## Multi-Session Spider

Use different session types in a single spider for optimal performance:

```python theme={null}
from scrapling.spiders import Spider, Request, Response
from scrapling.fetchers import FetcherSession, AsyncStealthySession

class MultiSessionSpider(Spider):
    name = "multi"
    start_urls = ["https://example.com/"]
    
    def configure_sessions(self, manager):
        # Fast HTTP session for most pages
        manager.add("fast", FetcherSession(impersonate="chrome"))
        # Stealth session for protected pages
        manager.add("stealth", AsyncStealthySession(headless=True), lazy=True)
    
    async def parse(self, response: Response):
        for link in response.css('a::attr(href)').getall():
            # Route protected pages through stealth session
            if "protected" in link:
                yield Request(link, sid="stealth", callback=self.parse_protected)
            else:
                yield Request(link, sid="fast")
    
    async def parse_protected(self, response: Response):
        # Handle protected pages
        data = response.css('.content::text').get()
        yield {"protected_data": data}

MultiSessionSpider().start()
```

## Adaptive Scraping

Scrapling can automatically relocate elements when website structure changes:

<Steps>
  <Step title="Enable adaptive mode">
    ```python theme={null}
    from scrapling.fetchers import StealthyFetcher

    StealthyFetcher.adaptive = True
    ```
  </Step>

  <Step title="Save element locations">
    ```python theme={null}
    page = StealthyFetcher.fetch('https://example.com', headless=True)

    # Save element signatures for future use
    products = page.css('.product', auto_save=True)
    ```
  </Step>

  <Step title="Relocate after changes">
    ```python theme={null}
    # Later, if website structure changes
    page = StealthyFetcher.fetch('https://example.com', headless=True)

    # Automatically find elements using saved signatures
    products = page.css('.product', adaptive=True)
    ```
  </Step>
</Steps>

## Navigation & Selection

Scrapling offers powerful element navigation:

```python theme={null}
from scrapling.fetchers import Fetcher

page = Fetcher.get('https://quotes.toscrape.com/')

# Multiple selection methods
quotes = page.css('.quote')                              # CSS selector
quotes = page.xpath('//div[@class="quote"]')           # XPath
quotes = page.find_all('div', class_='quote')           # BeautifulSoup-style
quotes = page.find_by_text('quote', tag='div')          # Text search

# Element navigation
first_quote = quotes[0]
author = first_quote.css('.author::text').get()
parent = first_quote.parent
children = first_quote.children
siblings = first_quote.siblings

# Find similar elements
similar = first_quote.find_similar()
```

<Tip>
  See [Selection Methods](/parsing/selectors) for comprehensive selector documentation.
</Tip>

## Command Line Usage

Scrape without writing code:

<CodeGroup>
  ```bash Interactive Shell theme={null}
  scrapling shell
  ```

  ```bash Extract to Markdown theme={null}
  scrapling extract get 'https://example.com' content.md
  ```

  ```bash Extract with CSS Selector theme={null}
  scrapling extract get 'https://example.com' content.txt \
    --css-selector '#main-content' \
    --impersonate 'chrome'
  ```

  ```bash Stealthy Extract theme={null}
  scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' \
    captchas.html \
    --css-selector '#padded_content a' \
    --solve-cloudflare
  ```
</CodeGroup>

<Note>
  * `.txt` extension extracts text content
  * `.md` extension extracts Markdown representation
  * `.html` extension extracts raw HTML
</Note>

## Next Steps

You're now ready to explore Scrapling's advanced features:

<CardGroup cols={2}>
  <Card title="Selection Methods" icon="crosshairs" href="/parsing/selectors">
    Master CSS, XPath, regex, and text search
  </Card>

  <Card title="Choose Your Fetcher" icon="compass" href="/fetching/choosing-fetcher">
    Learn when to use each fetcher type
  </Card>

  <Card title="Build Advanced Spiders" icon="spider" href="/spiders/getting-started">
    Concurrent crawls with pause/resume
  </Card>

  <Card title="Proxy Rotation" icon="rotate" href="/fetching/proxy-rotation">
    Built-in proxy rotation strategies
  </Card>

  <Card title="Interactive Shell" icon="terminal" href="/cli/interactive-shell">
    Speed up development with IPython
  </Card>

  <Card title="MCP Server" icon="robot" href="/ai/mcp-server">
    AI-assisted web scraping
  </Card>
</CardGroup>

## Common Patterns

<AccordionGroup>
  <Accordion title="Handling Pagination">
    ```python theme={null}
    from scrapling.fetchers import Fetcher

    page = Fetcher.get('https://quotes.toscrape.com/')

    while True:
        # Extract data from current page
        quotes = page.css('.quote .text::text').getall()
        print(quotes)
        
        # Check for next page
        next_link = page.css('.next a::attr(href)').get()
        if not next_link:
            break
        
        # Fetch next page
        page = Fetcher.get(f'https://quotes.toscrape.com{next_link}')
    ```
  </Accordion>

  <Accordion title="Extracting Attributes">
    ```python theme={null}
    # Get href attributes
    links = page.css('a::attr(href)').getall()

    # Get data attributes
    product_ids = page.css('.product::attr(data-id)').getall()

    # Get multiple attributes
    for link in page.css('a'):
        url = link.attrib.get('href')
        title = link.attrib.get('title')
    ```
  </Accordion>

  <Accordion title="JSON Data Extraction">
    ```python theme={null}
    # Extract JSON from script tags
    json_data = page.css('script#data::text').get()

    # Parse JSON attributes
    schema = page.css('[schema]').attrib['schema'].json()

    # Extract all text as JSON-ready
    data = {
        "title": page.css('h1::text').get(),
        "price": page.css('.price::text').get(),
        "description": page.css('.description::text').get(),
    }
    ```
  </Accordion>

  <Accordion title="Error Handling">
    ```python theme={null}
    from scrapling.fetchers import Fetcher

    try:
        page = Fetcher.get('https://example.com', timeout=10)
        
        if page.status != 200:
            print(f"Error: Status {page.status}")
        else:
            data = page.css('.content::text').get()
            
    except Exception as e:
        print(f"Failed to fetch: {e}")
    ```
  </Accordion>
</AccordionGroup>
