Library / SDK
Lysagxra/BunkrDownloader avatar
Lysagxra/BunkrDownloader

BunkrDownloader: pulling whole Bunkr albums to disk with one command

Efficient downloader for Bunkr

578 stars64 forksPythonGPL-3.0

At a glance

What is it?
BunkrDownloader is a Python script that fetches images and videos from Bunkr album and file URLs, with concurrent album downloads, filename filters for including and excluding items, a batch mode driven by a text file, and a progress display. It is GPL-3.0 licensed and needs Python 3.11 or newer.
Who is it for?
Adopt BunkrDownloader if you need to archive a Bunkr album or a set of albums to local disk, and you want filename level control rather than a whole album dumped into one folder. Skip it if the platform itself offers you a download, since the tool exists because the Bunkr interface does not, and skip it if you need authenticated or private content, since the tool works from public URLs.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

It exists because the site does not offer a download

BunkrDownloader is a Python Bunkr downloader that fetches images and videos from URLs, supporting both Bunkr albums and individual file URLs, logging issues and enabling concurrent downloads for efficiency. The framing in the project description is accurate about the scope, and it is worth naming the problem it solves plainly, which is that the hosting site has no download button for an album. So the tool parses the album page, finds the media items, and pulls the files. The dependency list tells you how, and it is short enough to read at a glance. BeautifulSoup with bs4 for HTML parsing, requests for HTTP requests, and rich for progress display in the terminal, with aiohttp in the requirements file for the concurrent album downloads. The project is licensed GPL-3.0, and the repository has a src/ directory alongside the two entry point scripts, a bunkr.toml.example configuration file, a requirements.txt, a CONTRIBUTING.md and an assets directory holding a demo recording. The recent releases are regular, with v1.3.1 on 2026-10-14, v1.3.0 on 2026-08-24 and v1.2.9 on 2026-08-14, and the last push was on 2026-10-14, so the code is actively maintained.

Installing is a clone and a pip install

The installation steps are the ones you would expect. You open a terminal in the folder where you want to install the tool, then clone the repository.

bash
git clone https://github.com/Lysagxra/BunkrDownloader.git

Then you change into the project directory.

bash
cd BunkrDownloader

And install the dependencies.

bash
pip install -r requirements.txt

The requirements file pins exact versions, with aiohttp at 3.14.3, beautifulsoup4 at 4.15.0, Requests at 2.34.2 and rich at 15.0.0. Exact pins for a four dependency script is unusual and slightly unfortunate, since it means the tool will not pick up fixes in those libraries without an explicit bump, and it means an environment with a newer aiohttp already installed will need that one downgraded. The Python floor of 3.11 or newer is the other thing to note, and it is reasonable given the pinned dependency versions. The downloader also works in a notebook environment, and the README explains why: when the script runs in something like Jupyter, excessive output may lead to performance issues or crashes, which is the sort of detail you only find after it happens.

One URL for an album, one for a file, and a dry run

A single download goes through downloader.py with a valid album or media URL, and the README gives two examples that show the two URL shapes.

bash
python3 downloader.py https://bunkr.si/a/PUK068QE       # Download album
python3 downloader.py https://bunkr.fi/f/gBrv5f8tAGlGW  # Download single media

The distinction is in the path, since an album lives under a path beginning with a and a single file under one beginning with f, and the tool works out which it has been given. The filename behaviour is a separate flag. By default the downloader may generate filenames based on the URL, and the --clean-name flag preserves the original filename found on the item page, which is what you want if you care about the names later. The dry run is the other flag worth knowing, since it lets you see what the tool would do without writing anything.

bash
python3 downloader.py --dry-run --clean-name <bunkr_url>

The flag names here are inconsistent in a small way, with the long options using hyphens while the usage examples sometimes use a different separator, so it is worth checking the exact spelling for the argument you need rather than assuming.

Filtering by filename, with an ignore list and an include list

The selective download feature is the one that turns this from a convenience into a usable archiving tool, because an album can contain a lot of content you do not want. The Ignore List is given with the --ignore argument and lets you skip any file from an album whose filename contains at least one of the specified strings, with items in the list separated by a space. The README's example is skipping certain extensions such as zip files.

bash
python3 downloader.py https://bunkr.si/a/PUK068QE --ignore .zip

The Include List is the mirror image, given with the --include argument, and downloads a file from an album only if its filename contains at least one of the listed strings, again space separated.

bash
python3 downloader.py https://bunkr.si/a/PUK068QE --include FullSizeRender

That second example is the interesting one, because it is how you pull only the full size renders out of an album that also carries thumbnails and previews. The two lists can be combined, since a name can be excluded by one and included by the other, and the interaction between them is the kind of detail worth testing on a small album before you point it at a large one. The substring matching on filenames is simple and predictable, which is both its strength and its limit, since it has no notion of file type or size.

Batch mode reads a text file, and the directory layout is automatic

Batch downloads go through main.py rather than downloader.py, and the difference is the input. The script reads URLs from a file named URLs.txt in the root of the project and downloads each one using the media downloader.

code
https://bunkr.si/a/PUK068QE
https://bunkr.fi/f/gBrv5f8tAGlGW
https://bunkr.fi/a/kVYLh49Q

The README is specific about the format, that each URL should be on its own line without any extra spaces, and that you can add as many URLs as you need following the same format. Then you run the script.

code
python3 main.py

The output location is controlled by --custom-path, and the default is a Downloads folder created within the script's directory, so the tool writes into its own checkout unless you tell it otherwise. Inside that folder each album gets its own subfolder named with the album title and the album id in parentheses, which is the automatic directory structure the feature list mentions and is what keeps two albums with the same title apart. The --no-album-folder flag skips that level and saves files directly into the download directory, and --no-download-folder skips the Downloads folder itself, with the README noting the two can be combined. There is also a custom path variant of the batch run.

bash
python3 main.py --custom-path <custom_path>

Retries, logging and the notebook friendly switch

The last operational details are the ones that decide whether a long run survives a flaky connection. If a download fails, the downloader will retry up to 5 times by default, and the --max-retries argument changes that, with allowed values of 0, meaning do not re-download, and larger. A value of 0 is the one to think about, because it turns a transient failure into a permanent gap in the archive.

bash
python3 downloader.py <bunkr_url> --max-retries 3

The notebook switch is the --disable-ui argument, which disables the progress bar and minimizes log messages for the Jupyter case described earlier.

code
python3 main.py --disable-ui

Logging runs to a file named session.log, and the README says to check it for any URLs that may have been blocked or had errors. That file is the audit trail for a batch job, and since the tool also logs URLs that encounter errors for troubleshooting, it is the artifact to keep when you are archiving something you care about. The progress indication during downloads comes from rich, which is also the library that would be responsible for most of the output noise in a notebook, which explains the pairing of the disable switch with the rich dependency.

Where BunkrDownloader is the wrong tool

The obvious limit is that the tool only understands one host, and it understands that host by scraping its pages. Any change to how the album page presents its media items, or a move to a different domain, and the tool needs updating to match, and the price of an update is that you maintain a fork. The README's own examples use more than one domain, bunkr.si and bunkr.fi, which is a hint that the domains are not stable and that the tool is expected to be pointed at whichever is current. The second limit is that there is no authentication story described, so this is a tool for public content, and if you need to fetch something that requires a session, you are on your own. The third is the dependency pinning, which as noted above will bite the first time one of those pinned versions is needed by something else in your environment. The fourth is worth stating plainly because it applies to any downloader built on a scraping approach, and it is the one to check before using the tool on anything that matters: whether the terms of the service permit downloading it, and whether the files are yours to download. The tool is a well made script for a narrow job, and using it on content you have the right to archive is straightforward.

Editorial conclusion

Adopt BunkrDownloader if you need to archive a Bunkr album or a set of albums to local disk, and you want filename level control rather than a whole album dumped into one folder. Skip it if the platform itself offers you a download, since the tool exists because the Bunkr interface does not, and skip it if you need authenticated or private content, since the tool works from public URLs. Verify first that the site domain you are given still serves the structure the scraper expects, that your Python is 3.11 or newer, and that you have checked the terms of the service for the files you are fetching.

Frequently asked questions

How do I install and run BunkrDownloader?

Clone the repository, change into the project directory, and run pip install -r requirements.txt, which needs Python 3.11 or newer. Then run python3 downloader.py with a Bunkr album or media URL, using the --dry-run flag to see what would happen without writing files.

How do I download only some files from a Bunkr album?

Use the --ignore argument to skip any file whose filename contains one of the space separated strings, and the --include argument to download a file only if its filename contains one of those strings. The README gives --ignore .zip to skip archives and --include FullSizeRender to pull only full size renders.

How do I download several Bunkr albums at once and control where files go?

Create a file named URLs.txt in the project root with one URL per line and no extra spaces, then run python3 main.py. Files land in a Downloads folder inside the script directory by default, or under the path given with --custom-path, with each album in its own subfolder unless you pass --no-album-folder.

Official sources

  1. Issues
  2. License: GPL-3.0
  3. Lysagxra/BunkrDownloader on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/lysagxra-bunkrdownloader.svg)](https://hysenlabs.com/projects/lysagxra-bunkrdownloader)

Was this useful?