> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jakan.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Scraper Operations

> Operations for scraping metadata from external sources.

Operations for scraping metadata from external sources.

Bases: `StashClientProtocol`

Mixin for scraper-related client methods.

## Functions

### list\_scrapers

```python theme={null}
list_scrapers(
    types: list[ScrapeContentType],
) -> list[Scraper]
```

List available scrapers filtered by content types.

Parameters:

| Name    | Type                      | Description                                                                                  | Default    |
| ------- | ------------------------- | -------------------------------------------------------------------------------------------- | ---------- |
| `types` | `list[ScrapeContentType]` | List of content types to filter scrapers by (GALLERY, IMAGE, MOVIE, GROUP, PERFORMER, SCENE) | *required* |

Returns:

| Type            | Description                                          |
| --------------- | ---------------------------------------------------- |
| `list[Scraper]` | List of Scraper objects matching the requested types |

Examples:

List all scene scrapers:

```python theme={null}
scrapers = await client.list_scrapers([ScrapeContentType.SCENE])
for scraper in scrapers:
    print(f"Scene scraper: {scraper.name}")
```

List multiple scraper types:

```python theme={null}
from stash_graphql_client.types import ScrapeContentType
scrapers = await client.list_scrapers([
    ScrapeContentType.SCENE,
    ScrapeContentType.PERFORMER
])
```

Check scraper capabilities:

```python theme={null}
scrapers = await client.list_scrapers([ScrapeContentType.SCENE])
for scraper in scrapers:
    if scraper.scene:
        print(f"{scraper.name} supports: {scraper.scene.supported_scrapes}")
        print(f"URLs: {scraper.scene.urls}")
```

### scrape\_single\_scene

```python theme={null}
scrape_single_scene(
    source: ScraperSourceInput,
    input: ScrapeSingleSceneInput,
) -> list[ScrapedScene]
```

Scrape for a single scene.

Parameters:

| Name     | Type                     | Description                                              | Default    |
| -------- | ------------------------ | -------------------------------------------------------- | ---------- |
| `source` | `ScraperSourceInput`     | Scraper source (scraper\_id or stash\_box\_endpoint)     | *required* |
| `input`  | `ScrapeSingleSceneInput` | Scene scraping input (query, scene\_id, or scene\_input) | *required* |

Returns:

| Type                 | Description                  |
| -------------------- | ---------------------------- |
| `list[ScrapedScene]` | List of ScrapedScene objects |

Examples:

Scrape by query string:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleSceneInput(query="scene title")
scenes = await client.scrape_single_scene(source, input)
```

Scrape by scene ID (using fingerprints):

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleSceneInput(scene_id="scene-456")
scenes = await client.scrape_single_scene(source, input)
```

Scrape from StashBox:

```python theme={null}
source = ScraperSourceInput(stash_box_endpoint="https://stashdb.org")
input = ScrapeSingleSceneInput(query="scene title")
scenes = await client.scrape_single_scene(source, input)
```

### scrape\_multi\_scenes

```python theme={null}
scrape_multi_scenes(
    source: ScraperSourceInput,
    input: ScrapeMultiScenesInput,
) -> list[list[ScrapedScene]]
```

Scrape for multiple scenes.

Parameters:

| Name     | Type                     | Description                                          | Default    |
| -------- | ------------------------ | ---------------------------------------------------- | ---------- |
| `source` | `ScraperSourceInput`     | Scraper source (scraper\_id or stash\_box\_endpoint) | *required* |
| `input`  | `ScrapeMultiScenesInput` | Multi-scene scraping input (scene\_ids)              | *required* |

Returns:

| Type                       | Description                                                      |
| -------------------------- | ---------------------------------------------------------------- |
| `list[list[ScrapedScene]]` | List of lists of ScrapedScene objects (one list per input scene) |

Examples:

Scrape multiple scenes:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeMultiScenesInput(scene_ids=["1", "2", "3"])
results = await client.scrape_multi_scenes(source, input)
for i, scenes in enumerate(results):
    print(f"Scene {i+1}: {len(scenes)} matches found")
```

### scrape\_single\_studio

```python theme={null}
scrape_single_studio(
    source: ScraperSourceInput,
    input: ScrapeSingleStudioInput,
) -> list[ScrapedStudio]
```

Scrape for a single studio.

Parameters:

| Name     | Type                      | Description                                             | Default    |
| -------- | ------------------------- | ------------------------------------------------------- | ---------- |
| `source` | `ScraperSourceInput`      | Scraper source (scraper\_id or stash\_box\_endpoint)    | *required* |
| `input`  | `ScrapeSingleStudioInput` | Studio scraping input (query - can be name or Stash ID) | *required* |

Returns:

| Type                  | Description                   |
| --------------------- | ----------------------------- |
| `list[ScrapedStudio]` | List of ScrapedStudio objects |

Examples:

Scrape studio by name:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleStudioInput(query="Studio Name")
studios = await client.scrape_single_studio(source, input)
```

### scrape\_single\_tag

```python theme={null}
scrape_single_tag(
    source: ScraperSourceInput, input: ScrapeSingleTagInput
) -> list[ScrapedTag]
```

Scrape for a single tag.

Parameters:

| Name     | Type                   | Description                                          | Default    |
| -------- | ---------------------- | ---------------------------------------------------- | ---------- |
| `source` | `ScraperSourceInput`   | Scraper source (scraper\_id or stash\_box\_endpoint) | *required* |
| `input`  | `ScrapeSingleTagInput` | Tag scraping input (query - can be name or Stash ID) | *required* |

Returns:

| Type               | Description                |
| ------------------ | -------------------------- |
| `list[ScrapedTag]` | List of ScrapedTag objects |

Examples:

Scrape tag by name:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleTagInput(query="Tag Name")
tags = await client.scrape_single_tag(source, input)
```

Scrape from StashBox:

```python theme={null}
source = ScraperSourceInput(stash_box_endpoint="https://stashdb.org")
input = ScrapeSingleTagInput(query="Tag Name")
tags = await client.scrape_single_tag(source, input)
```

### scrape\_single\_performer

```python theme={null}
scrape_single_performer(
    source: ScraperSourceInput,
    input: ScrapeSinglePerformerInput,
) -> list[ScrapedPerformer]
```

Scrape for a single performer.

Parameters:

| Name     | Type                         | Description                                                          | Default    |
| -------- | ---------------------------- | -------------------------------------------------------------------- | ---------- |
| `source` | `ScraperSourceInput`         | Scraper source (scraper\_id or stash\_box\_endpoint)                 | *required* |
| `input`  | `ScrapeSinglePerformerInput` | Performer scraping input (query, performer\_id, or performer\_input) | *required* |

Returns:

| Type                     | Description                      |
| ------------------------ | -------------------------------- |
| `list[ScrapedPerformer]` | List of ScrapedPerformer objects |

Examples:

Scrape by query string:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSinglePerformerInput(query="Performer Name")
performers = await client.scrape_single_performer(source, input)
```

Scrape by performer ID:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSinglePerformerInput(performer_id="123")
performers = await client.scrape_single_performer(source, input)
```

### scrape\_multi\_performers

```python theme={null}
scrape_multi_performers(
    source: ScraperSourceInput,
    input: ScrapeMultiPerformersInput,
) -> list[list[ScrapedPerformer]]
```

Scrape for multiple performers.

Parameters:

| Name     | Type                         | Description                                          | Default    |
| -------- | ---------------------------- | ---------------------------------------------------- | ---------- |
| `source` | `ScraperSourceInput`         | Scraper source (scraper\_id or stash\_box\_endpoint) | *required* |
| `input`  | `ScrapeMultiPerformersInput` | Multi-performer scraping input (performer\_ids)      | *required* |

Returns:

| Type                           | Description                                                              |
| ------------------------------ | ------------------------------------------------------------------------ |
| `list[list[ScrapedPerformer]]` | List of lists of ScrapedPerformer objects (one list per input performer) |

Examples:

Scrape multiple performers:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeMultiPerformersInput(performer_ids=["1", "2", "3"])
results = await client.scrape_multi_performers(source, input)
for i, performers in enumerate(results):
    print(f"Performer {i+1}: {len(performers)} matches found")
```

### scrape\_single\_gallery

```python theme={null}
scrape_single_gallery(
    source: ScraperSourceInput,
    input: ScrapeSingleGalleryInput,
) -> list[ScrapedGallery]
```

Scrape for a single gallery.

Parameters:

| Name     | Type                       | Description                                                    | Default    |
| -------- | -------------------------- | -------------------------------------------------------------- | ---------- |
| `source` | `ScraperSourceInput`       | Scraper source (scraper\_id or stash\_box\_endpoint)           | *required* |
| `input`  | `ScrapeSingleGalleryInput` | Gallery scraping input (query, gallery\_id, or gallery\_input) | *required* |

Returns:

| Type                   | Description                    |
| ---------------------- | ------------------------------ |
| `list[ScrapedGallery]` | List of ScrapedGallery objects |

Examples:

Scrape by query string:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleGalleryInput(query="gallery title")
galleries = await client.scrape_single_gallery(source, input)
```

Scrape by gallery ID:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleGalleryInput(gallery_id="456")
galleries = await client.scrape_single_gallery(source, input)
```

### scrape\_single\_movie

```python theme={null}
scrape_single_movie(
    source: ScraperSourceInput,
    input: ScrapeSingleMovieInput,
) -> list[ScrapedMovie]
```

Scrape for a single movie.

**Deprecated:** Use `scrape_single_group` instead.

Parameters:

| Name     | Type                     | Description                                              | Default    |
| -------- | ------------------------ | -------------------------------------------------------- | ---------- |
| `source` | `ScraperSourceInput`     | Scraper source (scraper\_id or stash\_box\_endpoint)     | *required* |
| `input`  | `ScrapeSingleMovieInput` | Movie scraping input (query, movie\_id, or movie\_input) | *required* |

Returns:

| Type                 | Description                  |
| -------------------- | ---------------------------- |
| `list[ScrapedMovie]` | List of ScrapedMovie objects |

Examples:

Scrape by query string:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleMovieInput(query="movie title")
movies = await client.scrape_single_movie(source, input)
```

### scrape\_single\_group

```python theme={null}
scrape_single_group(
    source: ScraperSourceInput,
    input: ScrapeSingleGroupInput,
) -> list[ScrapedGroup]
```

Scrape for a single group.

Parameters:

| Name     | Type                     | Description                                              | Default    |
| -------- | ------------------------ | -------------------------------------------------------- | ---------- |
| `source` | `ScraperSourceInput`     | Scraper source (scraper\_id or stash\_box\_endpoint)     | *required* |
| `input`  | `ScrapeSingleGroupInput` | Group scraping input (query, group\_id, or group\_input) | *required* |

Returns:

| Type                 | Description                  |
| -------------------- | ---------------------------- |
| `list[ScrapedGroup]` | List of ScrapedGroup objects |

Examples:

Scrape by query string:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleGroupInput(query="group title")
groups = await client.scrape_single_group(source, input)
```

Scrape by group ID:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleGroupInput(group_id="789")
groups = await client.scrape_single_group(source, input)
```

### scrape\_single\_image

```python theme={null}
scrape_single_image(
    source: ScraperSourceInput,
    input: ScrapeSingleImageInput,
) -> list[ScrapedImage]
```

Scrape for a single image.

Parameters:

| Name     | Type                     | Description                                              | Default    |
| -------- | ------------------------ | -------------------------------------------------------- | ---------- |
| `source` | `ScraperSourceInput`     | Scraper source (scraper\_id or stash\_box\_endpoint)     | *required* |
| `input`  | `ScrapeSingleImageInput` | Image scraping input (query, image\_id, or image\_input) | *required* |

Returns:

| Type                 | Description                  |
| -------------------- | ---------------------------- |
| `list[ScrapedImage]` | List of ScrapedImage objects |

Examples:

Scrape by query string:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleImageInput(query="image title")
images = await client.scrape_single_image(source, input)
```

Scrape by image ID:

```python theme={null}
source = ScraperSourceInput(scraper_id="scraper-123")
input = ScrapeSingleImageInput(image_id="101")
images = await client.scrape_single_image(source, input)
```

### scrape\_url

```python theme={null}
scrape_url(url: str, ty: ScrapeContentType) -> Any
```

Scrape content based on a URL.

Parameters:

| Name  | Type                | Description                                                                | Default    |
| ----- | ------------------- | -------------------------------------------------------------------------- | ---------- |
| `url` | `str`               | The URL to scrape                                                          | *required* |
| `ty`  | `ScrapeContentType` | Type of content to scrape (GALLERY, IMAGE, MOVIE, GROUP, PERFORMER, SCENE) | *required* |

Returns:

| Type  | Description                                                                 |
| ----- | --------------------------------------------------------------------------- |
| `Any` | ScrapedContent union type (could be any scraped type based on ty parameter) |

<Note>
  Returns ScrapedStudio, ScrapedTag, ScrapedScene, ScrapedGallery, ScrapedImage, ScrapedMovie, ScrapedGroup, or ScrapedPerformer depending on the content type.
</Note>

Examples:

Scrape a scene from URL:

```python theme={null}
from stash_graphql_client.types import ScrapeContentType
content = await client.scrape_url(
    "https://example.com/scene/123",
    ScrapeContentType.SCENE
)
if content:
    print(f"Scraped scene: {content.title}")
```

Scrape a performer from URL:

```python theme={null}
content = await client.scrape_url(
    "https://example.com/performer/456",
    ScrapeContentType.PERFORMER
)
if content:
    print(f"Scraped performer: {content.name}")
```

### scrape\_performer\_url

```python theme={null}
scrape_performer_url(url: str) -> ScrapedPerformer | None
```

Scrape a complete performer record based on a URL.

Parameters:

| Name  | Type  | Description                      | Default    |
| ----- | ----- | -------------------------------- | ---------- |
| `url` | `str` | The URL to scrape performer from | *required* |

Returns:

| Type                       | Description                                           |
| -------------------------- | ----------------------------------------------------- |
| `ScrapedPerformer \| None` | ScrapedPerformer object if successful, None otherwise |

Examples:

Scrape performer from URL:

```python theme={null}
performer = await client.scrape_performer_url("https://example.com/performer/123")
if performer:
    print(f"Name: {performer.name}")
    print(f"Birthdate: {performer.birthdate}")
    print(f"Gender: {performer.gender}")
```

### scrape\_scene\_url

```python theme={null}
scrape_scene_url(url: str) -> ScrapedScene | None
```

Scrape a complete scene record based on a URL.

Parameters:

| Name  | Type  | Description                  | Default    |
| ----- | ----- | ---------------------------- | ---------- |
| `url` | `str` | The URL to scrape scene from | *required* |

Returns:

| Type                   | Description                                       |
| ---------------------- | ------------------------------------------------- |
| `ScrapedScene \| None` | ScrapedScene object if successful, None otherwise |

Examples:

Scrape scene from URL:

```python theme={null}
scene = await client.scrape_scene_url("https://example.com/scene/123")
if scene:
    print(f"Title: {scene.title}")
    print(f"Date: {scene.date}")
    print(f"Studio: {scene.studio.name if scene.studio else 'Unknown'}")
```

### scrape\_gallery\_url

```python theme={null}
scrape_gallery_url(url: str) -> ScrapedGallery | None
```

Scrape a complete gallery record based on a URL.

Parameters:

| Name  | Type  | Description                    | Default    |
| ----- | ----- | ------------------------------ | ---------- |
| `url` | `str` | The URL to scrape gallery from | *required* |

Returns:

| Type                     | Description                                         |
| ------------------------ | --------------------------------------------------- |
| `ScrapedGallery \| None` | ScrapedGallery object if successful, None otherwise |

Examples:

Scrape gallery from URL:

```python theme={null}
gallery = await client.scrape_gallery_url("https://example.com/gallery/123")
if gallery:
    print(f"Title: {gallery.title}")
    print(f"Date: {gallery.date}")
    print(f"Performers: {len(gallery.performers or [])}")
```

### scrape\_image\_url

```python theme={null}
scrape_image_url(url: str) -> ScrapedImage | None
```

Scrape a complete image record based on a URL.

Parameters:

| Name  | Type  | Description                  | Default    |
| ----- | ----- | ---------------------------- | ---------- |
| `url` | `str` | The URL to scrape image from | *required* |

Returns:

| Type                   | Description                                       |
| ---------------------- | ------------------------------------------------- |
| `ScrapedImage \| None` | ScrapedImage object if successful, None otherwise |

Examples:

Scrape image from URL:

```python theme={null}
image = await client.scrape_image_url("https://example.com/image/123")
if image:
    print(f"Title: {image.title}")
    print(f"Date: {image.date}")
    print(f"Tags: {len(image.tags or [])}")
```

### scrape\_movie\_url

```python theme={null}
scrape_movie_url(url: str) -> ScrapedMovie | None
```

Scrape a complete movie record based on a URL.

**Deprecated:** Use `scrape_group_url` instead.

Parameters:

| Name  | Type  | Description                  | Default    |
| ----- | ----- | ---------------------------- | ---------- |
| `url` | `str` | The URL to scrape movie from | *required* |

Returns:

| Type                   | Description                                       |
| ---------------------- | ------------------------------------------------- |
| `ScrapedMovie \| None` | ScrapedMovie object if successful, None otherwise |

Examples:

Scrape movie from URL:

```python theme={null}
movie = await client.scrape_movie_url("https://example.com/movie/123")
if movie:
    print(f"Name: {movie.name}")
    print(f"Date: {movie.date}")
    print(f"Duration: {movie.duration}")
```

### scrape\_group\_url

```python theme={null}
scrape_group_url(url: str) -> ScrapedGroup | None
```

Scrape a complete group record based on a URL.

Parameters:

| Name  | Type  | Description                  | Default    |
| ----- | ----- | ---------------------------- | ---------- |
| `url` | `str` | The URL to scrape group from | *required* |

Returns:

| Type                   | Description                                       |
| ---------------------- | ------------------------------------------------- |
| `ScrapedGroup \| None` | ScrapedGroup object if successful, None otherwise |

Examples:

Scrape group from URL:

```python theme={null}
group = await client.scrape_group_url("https://example.com/group/123")
if group:
    print(f"Name: {group.name}")
    print(f"Date: {group.date}")
    print(f"Synopsis: {group.synopsis}")
```

### reload\_scrapers

```python theme={null}
reload_scrapers() -> bool
```

Reload all scrapers from configuration.

Returns:

| Type   | Description                         |
| ------ | ----------------------------------- |
| `bool` | True if successful, False otherwise |

Examples:

Reload scrapers after configuration change:

```python theme={null}
success = await client.reload_scrapers()
if success:
    print("Scrapers reloaded successfully")
    # List scrapers to verify
    scrapers = await client.list_scrapers([ScrapeContentType.SCENE])
    print(f"Found {len(scrapers)} scene scrapers")
```

### submit\_stashbox\_fingerprints

```python theme={null}
submit_stashbox_fingerprints(
    input_data: StashBoxFingerprintSubmissionInput
    | dict[str, Any],
) -> bool
```

Submit fingerprints to StashBox.

Parameters:

| Name         | Type                                                   | Description                                             | Default    |
| ------------ | ------------------------------------------------------ | ------------------------------------------------------- | ---------- |
| `input_data` | `StashBoxFingerprintSubmissionInput \| dict[str, Any]` | StashBoxFingerprintSubmissionInput object or dictionary | *required* |

Returns:

| Type   | Description        |
| ------ | ------------------ |
| `bool` | True if successful |

### submit\_stashbox\_scene\_draft

```python theme={null}
submit_stashbox_scene_draft(
    input_data: StashBoxDraftSubmissionInput
    | dict[str, Any],
) -> str
```

Submit scene draft to StashBox.

Parameters:

| Name         | Type                                             | Description                                       | Default    |
| ------------ | ------------------------------------------------ | ------------------------------------------------- | ---------- |
| `input_data` | `StashBoxDraftSubmissionInput \| dict[str, Any]` | StashBoxDraftSubmissionInput object or dictionary | *required* |

Returns:

| Type  | Description |
| ----- | ----------- |
| `str` | Draft ID    |

### submit\_stashbox\_performer\_draft

```python theme={null}
submit_stashbox_performer_draft(
    input_data: StashBoxDraftSubmissionInput
    | dict[str, Any],
) -> str
```

Submit performer draft to StashBox.

Parameters:

| Name         | Type                                             | Description                                       | Default    |
| ------------ | ------------------------------------------------ | ------------------------------------------------- | ---------- |
| `input_data` | `StashBoxDraftSubmissionInput \| dict[str, Any]` | StashBoxDraftSubmissionInput object or dictionary | *required* |

Returns:

| Type  | Description |
| ----- | ----------- |
| `str` | Draft ID    |

### stashbox\_batch\_performer\_tag

```python theme={null}
stashbox_batch_performer_tag(
    input_data: dict[str, Any],
) -> str
```

Batch tag performers from StashBox.

Parameters:

| Name         | Type             | Description                          | Default    |
| ------------ | ---------------- | ------------------------------------ | ---------- |
| `input_data` | `dict[str, Any]` | Batch performer tag input dictionary | *required* |

Returns:

| Type  | Description |
| ----- | ----------- |
| `str` | Job ID      |

### stashbox\_batch\_studio\_tag

```python theme={null}
stashbox_batch_studio_tag(
    input_data: dict[str, Any],
) -> str
```

Batch tag studios from StashBox.

Parameters:

| Name         | Type             | Description                       | Default    |
| ------------ | ---------------- | --------------------------------- | ---------- |
| `input_data` | `dict[str, Any]` | Batch studio tag input dictionary | *required* |

Returns:

| Type  | Description |
| ----- | ----------- |
| `str` | Job ID      |

### stashbox\_batch\_tag\_tag

```python theme={null}
stashbox_batch_tag_tag(input_data: dict[str, Any]) -> str
```

Batch tag tags from StashBox.

Parameters:

| Name         | Type             | Description                                        | Default    |
| ------------ | ---------------- | -------------------------------------------------- | ---------- |
| `input_data` | `dict[str, Any]` | Batch tag input dictionary (StashBoxBatchTagInput) | *required* |

Returns:

| Type  | Description |
| ----- | ----------- |
| `str` | Job ID      |
