You said:
gallery-dl, download instagram profile with whole metadata
Here’s how to use gallery-dl to download an entire Instagram profile including as much metadata as Instagram provides (captions, timestamps, likes, comments count, etc.).
⚠️ Instagram requires authentication for full access. Without login cookies, metadata will be incomplete or downloads may fail.
bashpip install -U gallery-dl
Verify:
bashgallery-dl --version
Log in to Instagram in your browser
Export cookies to a file
Chrome/Firefox extension: cookies.txt or Get cookies.txt
Save as:
textcookies.txt
bashgallery-dl \ --cookies cookies.txt \ https://www.instagram.com/USERNAME/
This downloads:
Photos & videos
Captions
Post dates
Like count
Comment count
Post IDs
Use a config file for maximum metadata.
bashmkdir -p ~/.config/gallery-dl
nano ~/.config/gallery-dl/config.json
json{
"extractor": {
"instagram": {
"cookies": "cookies.txt",
"videos": true,
"include": "all",
"sleep-request": 2,
"sleep": 1,
"directory": ["instagram", "{username}"],
"filename": "{date:%Y-%m-%d}_{shortcode}_{typename}",
"postprocessors": [
{
"name": "metadata",
"event": "post",
"filename": "{filename}.json",
"mode": "json"
}
]
}
}
}
This creates a .json metadata file per post.
Each {filename}.json includes:
shortcode
caption
timestamp
like_count
comment_count
owner.username
is_video
video_duration
location
hashtags
mentions
Media URLs
Carousel info (for multi-posts)
bashgallery-dl --cookies cookies.txt instagram:stories USERNAME
bashgallery-dl --cookies cookies.txt instagram:highlights USERNAME
Instagram is aggressive with scraping.
Recommended:
json"sleep-request": 2,
"sleep": 1
Optional:
bash--limit-rate 500K
Example:
bashls instagram/USERNAME/*.json
Inspect:
bashjq . instagram/USERNAME/2024-01-01_ABC123_Image.json
❌ 403 / Login required
→ Cookies expired → re-export cookies
❌ Missing captions or likes
→ Not logged in OR using old gallery-dl
❌ Only thumbnails downloaded
→ Set "videos": true
To embed metadata into files:
bashpip install gallery-dl[metadata]
If you want:
Single JSON for whole profile
CSV export
Download private accounts
Reels-only
Stories with captions
Tell me 👍
This is normal on Debian / Ubuntu (Python 3.12+). Your system Python is PEP 668 “externally managed”, so pip install is blocked on purpose.
You have three correct ways to install gallery-dl.
👉 Use option A or B (recommended).
Installs gallery-dl in its own isolated environment and works system-wide.
bashsudo apt install pipx python3-venv
pipx ensurepath
Log out & back in (or restart shell).
bashpipx install gallery-dl
bashgallery-dl --version
✔ No virtualenv management
✔ Safe
✔ Recommended by Debian
Best if you want full control or plugins.
bashsudo apt install python3-full python3-venv
bashpython3 -m venv ~/venvs/gallery-dl
bashsource ~/venvs/gallery-dl/bin/activate
bashpip install -U gallery-dl
bashgallery-dl --version
To exit later:
bashdeactivate
bashpip install --break-system-packages gallery-dl
⚠️ Can break your OS Python. Avoid.
config.json (important)Regardless of install method:
bash~/.config/gallery-dl/config.json
Cookies path example:
json"cookies": "/home/YOURUSER/cookies.txt"
Both pipx and venv support:
Cookies
Full metadata
JSON export
Stories / reels / highlights
pipx + config file + cookies.txt
If you want, tell me:
your distro (Ubuntu, Debian, Mint, etc.)
whether you want CSV, single JSON, or Reels-only
and I’ll tailor it exactly 👍
Below is the clean, complete way to download a Facebook album with all available metadata using gallery-dl.
⚠️ Facebook requires login cookies for albums, private content, and full metadata. Without cookies you’ll get little or nothing.
(From earlier, pipx is ideal)
bashgallery-dl --version
Log in to Facebook in your browser
Use a browser extension:
Get cookies.txt (Chrome / Firefox)
Export cookies as:
textcookies.txt
Place it somewhere safe, e.g.:
bash~/.config/gallery-dl/cookies.txt
Gallery-dl supports all of these:
texthttps://www.facebook.com/media/set/?set=a.ALBUM_ID https://www.facebook.com/USERNAME/albums/ALBUM_ID/ https://www.facebook.com/photo/?fbid=PHOTO_ID&set=a.ALBUM_ID
bashgallery-dl \ --cookies ~/.config/gallery-dl/cookies.txt \ https://www.facebook.com/USERNAME/albums/ALBUM_ID/
This already downloads:
Full-resolution photos/videos
Captions
Upload timestamps
Photo IDs
bashmkdir -p ~/.config/gallery-dl
nano ~/.config/gallery-dl/config.json
json{
"extractor": {
"facebook": {
"cookies": "~/.config/gallery-dl/cookies.txt",
"videos": true,
"include": "all",
"directory": ["facebook", "{author[name]}", "{album[name]|Album}"],
"filename": "{date:%Y-%m-%d}_{id}",
"sleep-request": 2,
"sleep": 1,
"postprocessors": [
{
"name": "metadata",
"event": "post",
"filename": "{filename}.json",
"mode": "json"
}
]
}
}
}
Each media item creates:
textphoto.jpg photo.json
The .json includes:
id
caption
created_time
album.name
album.id
author.name
author.id
like_count (when visible)
comment_count
is_video
video_duration
Original media URLs
⚠️ Facebook does not expose commenter names or full reactions reliably anymore.
bashgallery-dl --range 1-5 \ https://www.facebook.com/USERNAME/albums/ALBUM_ID/
Facebook is aggressive.
Recommended (already in config):
json"sleep-request": 2,
"sleep": 1
Optional CLI:
bash--limit-rate 500K
❌ Login required / empty album
→ Cookies expired → re-export
❌ Low resolution images
→ Must be logged in
→ Album privacy must allow you access
❌ Missing captions
→ Some albums are “media-only”
→ Facebook often strips old captions
I can show you how to:
Export single album JSON
Convert metadata to CSV
Download private group albums
Download tagged photos
Separate videos vs photos
Mirror entire Facebook pages
Just tell me what you want next 👍
Got it — here’s how to push gallery-dl (Facebook) as far as it can go in terms of postprocessors + metadata extraction.
I’ll be very clear about what is possible vs impossible, because Facebook hard-limits data.
Gallery-dl can only save metadata that Facebook actually exposes to logged-in users.
❌ Not possible (Facebook blocks this):
Full commenter lists
Reaction breakdowns (👍❤️😂 etc.)
User profile metadata of likers
EXIF from Facebook images (already stripped)
✅ Possible:
Full media metadata
Album + author info
Captions
Timestamps
IDs
Video properties
URLs
Group/page context
Structured JSON, TXT, CSV
Gallery-dl supports these postprocessors (relevant ones):
| Postprocessor | Purpose |
|---|---|
metadata | Save JSON metadata |
json | Alternate JSON writer |
exec | Run custom scripts |
mtime | Set file timestamp |
zip | Archive albums |
checksum | Hash verification |
classify | Custom folder logic |
This config enables everything gallery-dl can extract.
json{
"extractor": {
"facebook": {
"cookies": "~/.config/gallery-dl/cookies.txt",
"include": "all",
"videos": true,
"directory": [
"facebook",
"{author[name]|unknown}",
"{album[name]|no_album}"
],
"filename": "{date:%Y-%m-%d_%H-%M-%S}_{id}",
"sleep-request": 2,
"sleep": 1,
"postprocessors": [
{
"name": "metadata",
"event": "post",
"filename": "{filename}.json",
"mode": "json"
},
{
"name": "mtime",
"event": "file"
},
{
"name": "checksum",
"event": "file",
"hash": "sha256"
}
]
}
}
}
Inside each .json file:
json"id"
"shortcode"
"is_video"
"video_duration"
"dimensions"
"media_url"
json"created_time"
"date"
json"caption"
"alt_text"
json"album": {
"id"
"name"
}
json"author": {
"id"
"name"
"url"
}
json"like_count"
"comment_count"
json"group"
"page"
"privacy"
"source_url"
Gallery-dl is per-post by design, but you can merge later.
jqbashjq -s '.' facebook/**/**/*.json > album_full.json
bashjq -r '
.[] |
[
.id,
.created_time,
.author.name,
.album.name,
.caption,
.like_count,
.comment_count,
.media_url
] | @csv
' album_full.json > album.csv
Example: auto-append metadata to a log file.
json{
"name": "exec",
"event": "post",
"command": [
"bash",
"-c",
"echo '{id},{created_time},{album[name]}' >> facebook_log.csv"
]
}
json{
"name": "zip",
"event": "after",
"filename": "{album[name]}.zip"
}
bashgallery-dl -K https://www.facebook.com/USERNAME/albums/ALBUM_ID/
This prints all fields, including hidden ones.
❌ “More postprocessors = more Facebook data”
✔ No — postprocessors only store / transform what Facebook already exposes.
❌ “Gallery-dl is missing likes/comments”
✔ Facebook stopped exposing them consistently.
Private group albums
Whole Facebook page mirror
Timeline photos
Tagged photos
Custom Python metadata processor
Tell me what you want and your OS 👍
Below is the maximum-coverage, realistic way to mirror an entire Facebook page with gallery-dl, including all media + all metadata Facebook still exposes.
This is as close to a true mirror as Facebook allows in 2025.
Even with login cookies, no tool can extract:
❌ Full comments
❌ Reaction breakdowns
❌ Lists of likers
❌ Full timelines as structured posts
❌ Shared/private-only content you can’t see manually
✔ What is possible:
All photos & videos
Albums
Timeline media
Reels (if accessible)
Captions
Timestamps
IDs
Page info
Engagement counts (limited)
Per-media JSON metadata
✔ Logged-in Facebook account
✔ Cookies exported (cookies.txt)
✔ gallery-dl installed (pipx or venv)
Cookies path used below:
text~/.config/gallery-dl/cookies.txt
To fully mirror a page, you must hit multiple endpoints:
| Content | URL |
|---|---|
| Albums | /photos/albums/ |
| Timeline photos | /photos/ |
| Videos | /videos/ |
| Reels (if present) | /reels/ |
| Tagged photos | /photos_of/ |
Example page:
texthttps://www.facebook.com/PAGENAME
Create/edit:
bash~/.config/gallery-dl/config.json
json{
"extractor": {
"facebook": {
"cookies": "~/.config/gallery-dl/cookies.txt",
"include": "all",
"videos": true,
"directory": [
"facebook",
"{author[name]|unknown}",
"{category|page}"
],
"filename": "{date:%Y-%m-%d_%H-%M-%S}_{id}",
"sleep-request": 2,
"sleep": 1,
"postprocessors": [
{
"name": "metadata",
"event": "post",
"filename": "{filename}.json",
"mode": "json"
},
{
"name": "mtime",
"event": "file"
},
{
"name": "checksum",
"event": "file",
"hash": "sha256"
}
]
}
}
}
bashgallery-dl https://www.facebook.com/PAGENAME/photos/albums/
bashgallery-dl https://www.facebook.com/PAGENAME/photos/
bashgallery-dl https://www.facebook.com/PAGENAME/videos/
bashgallery-dl https://www.facebook.com/PAGENAME/reels/
bashgallery-dl https://www.facebook.com/PAGENAME/photos_of/
📌 These commands do not duplicate files — gallery-dl deduplicates by ID.
textfacebook/ └── Page Name/ └── page/ ├── 2018-06-01_123456789.jpg ├── 2018-06-01_123456789.json ├── 2019-02-12_987654321.mp4 ├── 2019-02-12_987654321.json └── ...
Each media item has:
File
Matching .json metadata
Inside .json:
id
created_time
source_url
media_url
is_video
video_duration
dimensions
caption
alt_text
author.id
author.name
author.url
category
like_count
comment_count
album.id
album.name
privacy
bashjq -s '.' facebook/Page\ Name/page/*.json > page_full.json
bashjq -r '
.[] |
[
.id,
.created_time,
.caption,
.author.name,
.like_count,
.comment_count,
.media_url
] | @csv
' page_full.json > page.csv
For pages with 10k+ posts:
✔ Use sleeps (already set)
✔ Expect hours/days
✔ Run per section (albums → photos → videos)
✔ Resume safely if interrupted
Resume automatically:
bashgallery-dl --download-archive archive.txt URL
bashgallery-dl -K https://www.facebook.com/PAGENAME/photos/
✔ This mirrors all accessible page media
✔ Preserves timestamps, captions, structure
✔ Produces machine-readable metadata
✔ Facebook limits are unavoidable
If you want next:
Private page / group mirror
Incremental syncing
Wayback-style HTML viewer
Python script to rebuild timeline
Media dedup across pages
Tell me 👍
Here’s the difference between these two Facebook album/photo URL formats:
?set=pb.<number>Example:
rubyhttps://www.facebook.com/media/set/?set=pb.61550654682264
pb. typically indicates a photo album set or gallery generated by Facebook’s photo viewer.
This prefix is often used in URLs for photo sets / albums when Facebook’s UI constructs links for albums or collections of photos.
It’s historically associated with older album formats where a. or pb. prefixes indicate album containers with numeric IDs that follow. Smash Balloon
This is the format that gallery tools and scrapers expect for an album.
?set=ecnf.<number>Example:
rubyhttps://www.facebook.com/media/set/?set=ecnf.61550654682264
ecnf. appears in shared/photo embed contexts or when Facebook is generating a collection based on an external context feed or sharing into different contexts.
These links are often seen when people share photos to timelines or through feeds where Facebook uses a more complex identifier (not always a static album).
The ecnf prefix doesn’t change the underlying media — it’s mostly part of Facebook’s internal URL/query parameter system to reference the same media set but under a different UI/encoding context (e.g., embed feed, external link, or shared page view). The Electronic Intifada
This format still represents a set of photos but uses a different prefix due to how the link was generated.
| Feature | pb.<id> | ecnf.<id> |
|---|---|---|
| Type | Standard Facebook album set | Facebook context feed set |
| Where it comes from | Typical album/gallery link | Shared/shared-feed based link |
| Works with scrapers | Yes | Yes (it refers to the same underlying media) |
| Differences | UI/URL prefix | UI/URL prefix only |
Both URLs ultimately point to the same photoset/album, just encoded with different internal prefixes that Facebook uses depending on how the link is generated (e.g., direct album view vs embed/shared context).
Tools like gallery-dl treat these as album identifiers, and both should be usable:
bashgallery-dl "https://www.facebook.com/media/set/?set=pb.61550654682264"
gallery-dl "https://www.facebook.com/media/set/?set=ecnf.61550654682264"
Both will refer to the same album media under different URL encodings.
If you want to dig deeper into how Facebook constructs these link prefixes and what each corresponds to internally (for example for scripting or robust scraping), I can outline how Facebook’s media URL encoding works and how to normalize them for tools like gallery-dl.