Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
bandcamp-fetch
Advanced tools
Library for scraping Bandcamp content.
Coverage:
Packaged as ESM + CJS hybrid module with typings.
npm i bandcamp-fetch --save
import bcfetch from 'bandcamp-fetch';
const results = await bcfetch.discovery.discover(...);
When you sign into Bandcamp, a "Cookie" is created to identify the user session. You can pass the value of this cookie to the library and gain access to your private collection as well as high-quality MP3 streams of purchased media:
bcfetch.setCookie('xxxx');
const album = await bcfetch.album.getInfo({
albumUrl: '...' // URL of purchased album
});
// Normal quality stream
const streamUrl = album.tracks[0].streamUrl;
// High quality stream - only available when `cookie` is set
const streamUrlHQ = album.tracks[0].streamUrlHQ;
Guide: How to obtain Cookie
BandcampFetch
The library exports a default BandcampFetch instance mainly for backward compatibility with previous versions:
// Imports the default `BandcampFetch` instance
import bcfetch from 'bandcamp-fetch';
You can also create separate instances. This is useful when you want to support multiple user sessions:
import { BandcampFetch } from 'bandcamp-fetch';
const bcfetch1 = new BandcampFetch({
cookie: 'xxxx' // Cookie for user session 1
});
const bcfetch2 = new BandcampFetch();
bcfetch2.setCookie('yyyy'); // Cookie for user sesion 2
To access the Discovery API:
import bcfetch from 'bandcamp-fetch';
const discovery = bcfetch.discovery;
const options = await discovery.getAvailableOptions();
const results = await discovery.discover(...);
Methods:
discover([params])
Fetches albums through Bandcamp Discover.
Params
params
: (DiscoverParams) (optional and all properties optional)
genre
: (string)subgenre
: (string) only valid when genre
is set to something other than 'all'.location
: (string)sortBy
: (string)artistRecommendationType
: (string) only valid when sortBy
is 'rec' (artist recommended).format
: (string)time
: (number)page
: (number)albumImageFormat
: (string | number | ImageFormat)artistImageFormat
: (string | number | ImageFormat)To see what values can be set in params
, call getAvailableOptions()
.
Returns
Promise resolving to DiscoverResult.
getAvailableOptions()
Fetches Bandcamp Discover options that can be used to configure params
for passing into discover()
.
Returns
Promise resolving to DiscoverOptions.
sanitizeDiscoverParams([params])
Sanitizes params
by setting default values for omitted properties and removing irrelevant or inapplicable ones.
Note that you don't have to call this method on params passed into discover()
as they will be sanitized automatically.
Params
params
: (DiscoverParams) (optional) the discover params to sanitize.Returns
Promise resolving to sanitized DiscoverParams.
To access the Image API:
import bcfetch, { ImageFormatFilter } from 'bandcamp-fetch';
const image = bcfetch.image;
const formats = await image.getFormats(ImageFormatFilter.Album);
Methods:
getFormats([filter])
Fetches the list of image formats used in Bandcamp.
Params
filter
: (ImageFormatFilter) (optional) if specified, narrows down the result to include only formats applicable to the specified value.Returns
Promise resolving to Array<ImageFormat>.
getImageFormat(target, [fallbackId])
Fetches the image format that matches target
. If none is found, the result will be null
.
Params
target
: (string | number | ImageFormat)
fallbackId
: (number) (optional) if no match is found for target
, try to obtain format with Id matching fallbackId
.Returns
Promise resolving to matching ImageFormat, or null
if none matches target
nor fallbackId
(if specified).
A band can be an artist or label. To access the Band API:
import bcfetch from 'bandcamp-fetch';
const band = bcfetch.band;
const info = await band.getInfo(...);
Methods:
getInfo(params)
Fetches information about an artist or label.
Params
params
: (BandAPIGetInfoParams)
bandUrl
: (string)imageFormat
: (string | number | ImageFormat) (optional)labelId
: (number) (optional)The method tries to assemble the most complete set of data by scraping the following pages (returning immediately at any point the data becomes complete):
bandUrl
bandUrl/music
)Sometimes, label information is missing for artists even when they do belong to a label. If you know the labelId
of the label that the artist belongs to, you can specify it in params
. This will ensure that label
will not be null
in the artist info. If you pass a label URL to this function, you can find the labelId
in the result.
Returns
Promise resolving to Artist or Label.
getLabelArtists(params)
Fetches the list of artists belonging to a label.
Params
params
: (BandAPIGetLabelArtistsParams)
labelUrl
: (string)imageFormat
: (string | number | ImageFormat) (optional)Returns
Promise resolving to Array<LabelArtist>.
getDiscography(params)
Fetches the list of albums and standalone tracks belonging to an artist or label.
Params
params
: (BandAPIGetDiscographyParams)
bandUrl
: (string)imageFormat
: (string | number | ImageFormat) (optional)Returns
Promise resolving to Array<Album | Track>.
To access the Album API:
import bcfetch from 'bandcamp-fetch';
const album = bcfetch.album;
const info = await album.getInfo(...);
Methods:
getInfo(params)
Fetches info about an album.
Params
params
: (AlbumAPIGetInfoParams)
albumUrl
: (string)albumImageFormat
: (string | number | ImageFormat) (optional)artistImageFormat
: (string | number | ImageFormat) (optional)includeRawData
: (boolean) (*optional)Returns
Promise resolving to Album.
If artist URL is not found in the scraped data, then
artist.url
will be set to the same value aspublisher.url
To access the Track API:
import bcfetch from 'bandcamp-fetch';
const track = bcfetch.track;
const info = await track.getInfo(...);
Methods:
getInfo(params)
Fetches info about a track.
Params
params
: (TrackAPIGetInfoParams)
trackUrl
: (string)albumImageFormat
: (string | number | ImageFormat) (optional)artistImageFormat
: (string | number | ImageFormat) (optional)includeRawData
: (boolean) (*optional)Returns
Promise resolving to Track.
If artist URL is not found in the scraped data, then
artist.url
will be set to the same value aspublisher.url
To access the Tag API:
import bcfetch from 'bandcamp-fetch';
const tag = bcfetch.tag;
const info = await tag.getInfo(...);
const highlights = await tag.getAlbumHighlights(...);
Methods:
list()
Fetches the full list of tags.
Returns
Promise resolving to TagList, which groups results into tags
(for non-location tags) and locations
(for location tags).
getAlbumHighlights(params)
Fetches album highlights for the tag referred to by params.tagUrl
.
Albums are placed in groups. Each group corresponds to a highlight category such as 'new and notable' and 'all-time best selling'.
Params
params
: (TagAPIGetAlbumHighlightsParams)
tagUrl
: (string)imageFormat
: (string | number | ImageFormat) (optional)Returns
Promise resolving to Array<AlbumHighlightsByTag>.
getReleases(params)
Fetches releases matching the tag referred to by params.tagUrl
.
Params
params
: (TagAPIGetReleasesParams)
tagUrl
: (string)imageFormat
: (string | number | ImageFormat) (optional)useHardcodedDefaultFilters
: (boolean) (optional) if true
, use hardcoded default values for filters not specified in params.filters
. If false
or unspecified, default filter values will be obtained by calling ``getReleasesAvailableFilters()
(extra query means slower performance).filters
: (object{ string: string | number | Array<string | number >}) (optional)page
: (number) (optional) 1 if omitted.params.filters
:Properties of params.filters
are not strictly defined. As of this documentation, the curent filters available on Bandcamp are:
location
: (number)tags
: (Array<string>) list of tags to match, in addition to the one referred to by params.tagUrl
.sort
: (string)format
: (string)Omitted properties are populated with default values obtained from params.tagUrl
. Possible filter values can be obtained by calling getReleasesAvailableFilters()
. For location
and tag
filters, you may look up additional values not returned by getReleasesAvailableFilters()
through getSuggestions()
of the Autocomplete API.
Returns
Promise resolving to ReleasesByTag.
getReleasesAvailableFilters(tagUrl)
Fetches the list of possible filter values for getReleases()
.
For location
and tag
filters, this method does not return an exhaustive list of values. You may use getSuggestions()
of the Autocomplete API to look up additional values.
Params
tagUrl
: (string) the URL of the tag for which filter values are to be returned.Returns
Promise resolving to Array<ReleasesByTag.Filter>.
To access the Show API:
import bcfetch from 'bandcamp-fetch';
const show = bcfetch.show;
const list = await show.list(...);
Methods:
list(params)
Fetches the full list of Bandcamp shows.
Each list entry contains basic info about a show. To obtain full details, pass its url
to getShow()
.
Params
params
: (ShowAPIListParams) (optional)
imageFormat
: (string | number | ImageFormat) (optional)Returns
Promise resolving to Array<Show>.
getShow(params)
Fetches full details about the Bandcamp show referred to by params.showUrl
.
Params
params
: (ShowAPIGetShowParams)
showUrl
: (string)albumImageFormat
: (string | number | ImageFormat) (optional)artistImageFormat
: (string | number | ImageFormat) (optional)showImageFormat
: (string | number | ImageFormat) (optional)Returns
Promise resolving to Show.
To access the Article API:
import bcfetch from 'bandcamp-fetch';
const article = bcfetch.article;
const list = await article.list(...);
Methods:
getCategories()
Fetches the list of Bandcamp Daily article categories. Categories are grouped into sections.
Returns
Promise resolving to Array<ArticleCategorySection>.
list(params)
Fetches the list of Bandcamp Daily articles under the category specified by params.categoryUrl
(or all categories if not specified).
Params
params
: (ArticleAPIListParams) (optional and all properties optional)
categoryUrl
: (string)imageFormat
: (string | number | ImageFormat)page
: (number)Returns
Promise resolving to ArticleList.
getArticle(params)
Fetches the contents of the Bandcamp Daily article at params.articleUrl
.
Params
params
: (ArticleAPIGetArticleParams)
articleUrl
: (string)albumImageFormat
: (string | number | ImageFormat) (optional)artistImageFormat
: (string | number | ImageFormat) (optional)includeRawData
: (boolean) (optional)Returns
Promise resolving to Article.
To access the Fan API:
import bcfetch from 'bandcamp-fetch';
const fan = bcfetch.fan;
const info = await fan.getInfo(...);
const collection = await fan.getCollection(...);
Methods:
getInfo(params)
Fetches info about a fan.
Params
params
: (FanAPIGetInfoParams)
username
: (string) (optional)imageFormat
: (string | number | ImageFormat) (optional)If username
is not specified, result will be obtained for the user of the session tied to the BandcampFetch
instance.
Returns
Promise resolving to Fan.
getCollection(params)
Fetches the list of albums and tracks in a fan's collection.
Params
params
: (FanAPIGetItemsParams)
target
: (string | FanItemsContinuation) (optional) if username (string) is specified, returns the first batch of items in the collection. To obtain further items, call the method again but, instead of username, pass continuation
from the result of the first call. If there are no further items available, continuation
will be null
.imageFormat
: (string | number | ImageFormat) (optional)If target
is not specified, result will be obtained for the user of the session tied to the BandcampFetch
instance.
Returns
Promise resolving to (FanPageItemsResult | FanContinuationItemsResult)<Album | Track>.
getWishlist(params)
Fetches the list of albums and tracks added to a fan's wishlist.
Params
params
: (FanAPIGetItemsParams)
target
: (string | FanItemsContinuation) (optional) if username (string) is specified, returns the first batch of items in the wishlist. To obtain further items, call the method again but, instead of username, pass continuation
from the result of the first call. If there are no further items available, continuation
will be null
.imageFormat
: (string | number | ImageFormat) (optional)If target
is not specified, result will be obtained for the user of the session tied to the BandcampFetch
instance.
Returns
Promise resolving to (FanPageItemsResult | FanContinuationItemsResult)<Album | Track>.
getFollowingArtistsAndLabels(params)
Fetches the list of artists and labels followed by a fan.
Params
params
: (FanAPIGetItemsParams)
target
: (string | FanItemsContinuation) (optional) if username (string) is specified, returns the first batch of artists and labels. To obtain further items, call the method again but, instead of username, pass continuation
from the result of the first call. If there are no further items available, continuation
will be null
.imageFormat
: (string | number | ImageFormat) (optional)If target
is not specified, result will be obtained for the user of the session tied to the BandcampFetch
instance.
Returns
Promise resolving to (FanPageItemsResult | FanContinuationItemsResult)<UserKind>.
getFollowingGenres(params)
Fetches the list of genres followed by a fan.
Each genre is actually a Bandcamp tag, so you can, for example, pass its url
to getReleases()
of the Tag API.
Params
params
: (FanAPIGetItemsParams)
target
: (string | FanItemsContinuation) (optional) if username (string) is specified, returns the first batch of genres. To obtain further items, call the method again but, instead of username, pass continuation
from the result of the first call. If there are no further items available, continuation
will be null
.imageFormat
: (string | number | ImageFormat) (optional)If target
is not specified, result will be obtained for the user of the session tied to the BandcampFetch
instance.
Returns
Promise resolving to (FanPageItemsResult | FanContinuationItemsResult)<Tag>.
To access the Search API:
import bcfetch from 'bandcamp-fetch';
const search = bcfetch.search;
const albums = await search.albums(...);
const all = await search.all(...);
Methods:
all(params) / artistsAndLabels(params) / albums(params) / tracks(params) / fans(params)
all(params)
: search all item typesartistsAndLabels(params)
: search artists and labelsalbums(params)
: search albumstracks(params)
: search tracksfans(params)
: search fansParams
params
: (SearchAPISearchParams)
query
: (string)page
: (number) (optional) 1 if omittedalbumImageFormat
: (string | number | ImageFormat) (optional)artistImageFormat
: (string | number | ImageFormat) (optional)Returns
Promise resolving to SearchResults<T
>, where T
depends on the item type being searched and can be one of:
You can use the type
property to determine the search result item type.
To access the Autocomplete API:
import bcfetch from 'bandcamp-fetch';
const autocomplete = bcfetch.autocomplete;
const suggestions = await autocomplete.getSuggestions(...);
Methods:
getSuggestions(params)
Fetches autocomplete suggestions for tags and locations, based on partial and full matches against `params.query`.
The value
property of returned suggestions can be used to set the location
or tags
property (as the case may be) of params.filters
that is passed into getReleases()
of the Tag API.
Params
params
: (AutocompleteAPIGetSuggestionsParams)
query
: (string)itemType
: (AutocompleteItemType) 'Tag' or 'Location'Returns
params.itemType
is AutocompleteItemType.Tag
, a Promise resolving to Array<AutocompleteTag>.params.itemType
is AutocompleteItemType.Location
, a Promise resolving to Array<AutocompleteLocation>.Stream URLs returned by Bandcamp can sometimes be invalid (perhaps expired). Before playing a stream, you are recommended to test its URL and refresh it if necessary with the Stream API.
To access the Stream API:
import bcfetch from 'bandcamp-fetch';
const stream = bcfetch.stream;
// Test a stream URL
const streamURL = '...';
const testResult = await stream.test(streamUrl);
if (!testResult.ok) {
const refreshedStreamURL = await stream.refresh(streamURL);
}
Methods:
test(url)
Tests validity of the stream given by `url`.
Params
url
: (string) the URL of the stream to testReturns
Promise resolving to StreamTestResult:
ok
: (boolean) whether the stream is validstatus
: (number) the HTTP response status code returned by the testrefresh(url)
Refreshes a stream URL.
Params
url
: (string) the URL of the stream to refreshReturns
Promise resolving to the refreshed URL of the stream or null
if no valid result was obtained.
Each BandcampFetch
instance comes with a rate limiter, which limits the number of requests made within a specific time period.
Rate limiting is useful when you need to make a large number of queries and don't want to run the risk of getting rejected by the server for making too many requests within a short time interval. If you get a '429 Too Many Requests' error, then you should consider using the rate limiter.
Each API has a limiter-enabled counterpart which you can access in the following manner:
import bcfetch from 'bandcamp-fetch';
// Album API - no limiter enabled
const albumAPI = bcfetch.album;
// Album API - limiter enabled
const limiterAlbumAPI = bcfetch.limiter.album;
The library uses Bottleneck for rate limiting. You can configure the rate limiter like this:
bcfetch.limiter.updateSettings({
maxConcurrent: 10, // default: 5
minTime: 100 // default: 200
});
updateSettings()
is just a passthrough function to Bottleneck. Check the Bottleneck doc for the list of options you can set.
Each BandcampFetch
instance has an in-memory cache for two types of data (as defined by CacheDataType):
CacheDataType.Page
- pages fetched during scrapingCacheDataType.Constants
- image formats and discover optionsTo access the cache:
import bcfetch, { CacheDataType } from 'bandcamp-fetch';
const cache = bcfetch.cache;
cache.setTTL(CacheDataType.Page, 500);
Methods:
setTTL(type, ttl)
Sets the expiry time, in seconds, of cache entries for the given data type.
Params
type
: (CacheDataType)TTL
: (number) expiry time in seconds (default: 300 for CacheDataType.Page
and 3600 for CacheDataType.Constants
)setMaxPages(maxPages)
Sets the maximum number of pages that can be stored in the cache. A negative value means unlimited. Default: 10.
Params
maxPages
: (number)clear([type])
Clears the cache entries for the specified data type (or all entries if no data type specified).
Params
type
: (CacheDataType) (optional)1.2.0
1.1.1
1.1.0
BandcampFetch
instances1.0.2
1.0.1
1.0.0 (breaking changes!)
safe-eval
dependency0.3.1-b.1
getFanCollection()
function0.3.0-b.1
0.2.2-b.1
itemType
option to search params0.2.1-b.20211020b
getArtistOrLabelInfo()
0.2.1-b.20211020
getArtistOrLabelInfo()
0.2.0-b.20211020
publisher
and label
to data fetched by getAlbumInfo()
and getTrackInfo()
labelId
to data fetched by getArtistOrLabelInfo(labelUrl)
labelId
option to getArtistOrLabelInfo()
for artist URLs...(no changelog for earlier versions due to laziness)
MIT
FAQs
Scrape Bandcamp content
The npm package bandcamp-fetch receives a total of 15 weekly downloads. As such, bandcamp-fetch popularity was classified as not popular.
We found that bandcamp-fetch demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.