# Bandcamp Scraper - Artists, Albums, Tracks & Tags (`cryptosignals/bandcamp-scraper`) Actor

Scrape Bandcamp albums, tracks, and artist profiles. Extract song titles, prices, genres, release dates, and fan counts. Discover indie music trends and analyze artist performance. Export to JSON, CSV, or Excel.

- **URL**: https://apify.com/cryptosignals/bandcamp-scraper.md
- **Developed by:** [CryptoSignals Agent](https://apify.com/cryptosignals) (community)
- **Categories:** Videos
- **Stats:** 4 total users, 2 monthly users, 85.7% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Bandcamp Scraper

Scrape [Bandcamp](https://bandcamp.com) — the leading platform for independent music — for search results, album details with full tracklists, and artist profiles with complete discographies. No authentication required.

### What is Bandcamp?

Bandcamp is a music platform where independent artists sell directly to fans. It hosts millions of albums and tracks across every genre imaginable, from jazz and electronic to punk and ambient. Artists set their own prices (including "name your price" / free), making it a goldmine for music market research and pricing analysis.

### Features

#### Search
Search Bandcamp's catalog by any query — genre, artist name, album title, mood, or keyword. Returns structured results with type classification (album, track, artist).

#### Album Details
Get complete album information from any Bandcamp album URL: tracklist with durations, pricing, tags, release date, and cover art.

#### Artist Info
Get artist profiles with bio, location, full discography listing, and genre tags from any Bandcamp artist URL.

### Input Schema

```json
{
    "action": "search",
    "query": "jazz",
    "maxItems": 20
}
````

#### Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `action` | string | Yes | `search`, `album`, or `artist` |
| `query` | string | For search | Search query text |
| `url` | string | For album/artist | Bandcamp URL to scrape |
| `maxItems` | integer | No | Max search results (default: 20, max: 200) |

### Output Examples

#### Search Results

```json
{
    "title": "Oncle Jazz",
    "artist": "Men I Trust",
    "url": "https://menitrust.bandcamp.com/album/oncle-jazz",
    "type": "album",
    "genre": "electronic",
    "releaseDate": "September 13, 2019",
    "thumbnail": "https://f4.bcbits.com/img/a3970465110_7.jpg"
}
```

#### Album Details

```json
{
    "title": "Oncle Jazz",
    "artist": "Men I Trust",
    "url": "https://menitrust.bandcamp.com/album/oncle-jazz",
    "tracks": [
        {
            "position": 1,
            "title": "Oncle Jazz",
            "url": "https://menitrust.bandcamp.com/track/oncle-jazz",
            "duration": 63.2
        }
    ],
    "trackCount": 24,
    "tags": ["electronic", "indie", "dream pop", "Montreal"],
    "releaseDate": "13 Sep 2019 00:00:00 GMT",
    "price": 0.0,
    "currency": "USD",
    "thumbnail": "https://f4.bcbits.com/img/a3970465110_10.jpg",
    "description": "24 track album"
}
```

#### Artist Info

```json
{
    "name": "Men I Trust",
    "url": "https://menitrust.bandcamp.com",
    "location": "Montreal, Quebec",
    "bio": "Men I Trust is a Canadian band...",
    "thumbnail": "https://f4.bcbits.com/img/...",
    "albums": [
        {
            "title": "Oncle Jazz",
            "url": "https://menitrust.bandcamp.com/album/oncle-jazz",
            "thumbnail": "https://f4.bcbits.com/img/a3970465110_7.jpg"
        }
    ],
    "albumCount": 6,
    "tags": ["electronic", "indie"]
}
```

### Use Cases

#### Music Market Research

Analyze pricing trends across genres. Bandcamp artists set their own prices, making it ideal for studying indie music economics. Track how many albums are free vs. paid, average price points by genre, and pricing strategies for successful artists.

```json
{"action": "search", "query": "synthwave", "maxItems": 100}
```

Collect 100 synthwave albums, then analyze the price distribution. Compare against other genres to find pricing sweet spots.

#### Playlist Curation and Music Discovery

Build curated playlists by searching for specific moods, genres, or subgenres. Bandcamp's tagging system is community-driven, so you can find extremely niche music.

```json
{"action": "search", "query": "lo-fi ambient", "maxItems": 50}
```

Use search results to discover artists, then drill into each with the `artist` action to explore their full catalogs.

#### Artist Discovery and A\&R

Labels and A\&R professionals can use this to discover emerging artists. Search for trending genres, then analyze artist discographies and release patterns.

```json
{"action": "artist", "url": "https://artist.bandcamp.com"}
```

Get complete discography, location (for booking/touring logistics), bio, and genre tags. Cross-reference multiple artists to find scenes and clusters.

#### Indie Music Pricing Analysis

Study how independent musicians price their work. Bandcamp's "name your price" model creates a unique dataset:

1. Search for a genre: `{"action": "search", "query": "jazz", "maxItems": 200}`
2. Get album details for each result to see actual prices
3. Analyze: What percentage is free? What's the median price? Do established artists charge more?

#### Genre and Tag Analysis

Map the Bandcamp genre ecosystem. Artists self-tag their work, creating a folksonomy of music classification:

1. Search across genres to collect tag data
2. Use album details to get full tag lists
3. Build a tag co-occurrence graph to understand genre relationships

#### Release Pattern Tracking

Monitor new releases in specific genres or from specific artists. Combine search (for genre-level monitoring) with artist scraping (for per-artist tracking) to build a release calendar.

#### Music Data Enrichment

Enrich your existing music database with Bandcamp data. If you have a list of artist names or album titles, use search to find their Bandcamp presence, then get full details.

#### Academic Research

Study the independent music ecosystem: geographical distribution of artists, genre evolution over time, pricing dynamics, and the relationship between tags and commercial success.

### Pricing

This actor uses pay-per-event pricing:

- **search-result**: Charged per search result returned
- **album-detail**: Charged per album scraped
- **artist-detail**: Charged per artist profile scraped

### Technical Details

- Uses `httpx` for async HTTP requests with connection pooling
- Parses JSON-LD structured data from album pages for maximum accuracy
- Falls back to HTML parsing via BeautifulSoup4 when structured data is unavailable
- Extracts `data-tralbum` and `data-band` embedded JSON from Bandcamp pages
- No authentication required — all data is from public pages
- Respects Bandcamp's server with sequential requests
- Handles pagination for search results automatically

### Limitations

- Only accesses publicly available information on Bandcamp
- Search results are limited to what Bandcamp's search returns (no API access)
- Rate limiting may apply for very large scrapes — use reasonable `maxItems` values
- Prices shown are the minimum/listed price; "name your price" items show 0.00

### FAQ

**Q: Does this require a Bandcamp account?**
A: No. All data is scraped from public HTML pages.

**Q: How fast is it?**
A: Search returns around 20 results per page load. Album and artist details take one request each. Typical runs complete in seconds.

**Q: Can I search by genre/tag?**
A: Yes — just use genre names as your search query. Bandcamp's search covers titles, artist names, tags, and descriptions.

**Q: What about "name your price" albums?**
A: These show as price 0.0 with a minPrice of 0.0 in the album details.

**Q: Can I get streaming URLs?**
A: The scraper focuses on metadata (titles, prices, tags). Streaming URLs are temporary and expire quickly.

### Getting Started

Install dependencies and run locally:

```bash
cd bandcamp-scraper
pip install -r requirements.txt
apify run --input '{"action": "search", "query": "jazz", "maxItems": 5}'
```

Or deploy to Apify:

```bash
apify login
apify push
```

### License

This project is licensed under the Apache License 2.0.

### Using proxies

Bandcamp uses Cloudflare protection that detects and blocks automated traffic patterns from datacenter IPs, returning 403 or challenge pages during bulk scraping. Residential proxies route requests through real ISP addresses that pass Cloudflare's trust checks. [ThorData](https://thordata.partnerstack.com/partner/0a0x4nzh) provides 200M+ residential IPs for reliable Bandcamp data collection at scale.

# Actor input Schema

## `action` (type: `string`):

What to do: search, album, or artist.

## `query` (type: `string`):

Search query (required for search action).

## `maxItems` (type: `integer`):

Maximum number of search results to return.

## Actor input object example

```json
{
  "action": "search",
  "query": "indie",
  "maxItems": 5
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "action": "search",
    "query": "indie",
    "maxItems": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("cryptosignals/bandcamp-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "action": "search",
    "query": "indie",
    "maxItems": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("cryptosignals/bandcamp-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "action": "search",
  "query": "indie",
  "maxItems": 5
}' |
apify call cryptosignals/bandcamp-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=cryptosignals/bandcamp-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Bandcamp Scraper - Artists, Albums, Tracks & Tags",
        "description": "Scrape Bandcamp albums, tracks, and artist profiles. Extract song titles, prices, genres, release dates, and fan counts. Discover indie music trends and analyze artist performance. Export to JSON, CSV, or Excel.",
        "version": "0.1",
        "x-build-id": "rXWlOhaqmdZt2cqz8"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/cryptosignals~bandcamp-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-cryptosignals-bandcamp-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/cryptosignals~bandcamp-scraper/runs": {
            "post": {
                "operationId": "runs-sync-cryptosignals-bandcamp-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/cryptosignals~bandcamp-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-cryptosignals-bandcamp-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "action"
                ],
                "properties": {
                    "action": {
                        "title": "Action",
                        "enum": [
                            "search",
                            "album",
                            "artist"
                        ],
                        "type": "string",
                        "description": "What to do: search, album, or artist.",
                        "default": "search"
                    },
                    "query": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Search query (required for search action).",
                        "default": "indie"
                    },
                    "maxItems": {
                        "title": "Max Items",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Maximum number of search results to return.",
                        "default": 5
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
