I read CoreMack's comment #2515003 earlier and it made me curious if there was an easy way to similarly break down my own posts by artist, copyright, character, gentag, etc; essentially something similar to the post reports. I've posted a lot over the last half year, and I wonder what some of the numbers are. I know I could do it manually by searching, but I am interested in a more automated method.
not sure about anything else, but for seeing what you personally upload most, the easiest way i know of is to go to the related tags page and put user:<your name> in the tag field. you can then filter this down by tag category.
I'm sure there are better ways to do this, especially the people who actually know the inner workings of Danbooru or database wizards, but I've whipped up this ai-assisted Python script to scrape your data. I've used something similar to collect the data for comment #2547977 on post #10000000.
In short, this script asks for an username. It then browses through https://danbooru.donmai.us/posts.json?limit=100&page={page}&tags=user%3A{user} and collects all post IDs. It then goes through each ID and counts all tags it finds grouped per category.
Python code
import requests
import time
import os
from collections import Counter
def fetch_ids(username, debug=False):
"""Fetch IDs from Danbooru for a given username."""
base_url = "https://danbooru.donmai.us/posts.json?limit=100&page={page}&tags=user%3A{user}"
page = 1
all_ids = []
while True:
url = base_url.format(page=page, user=username)
print(f"Fetching page {page} for user '{username}'...")
response = requests.get(url)
response.raise_for_status()
data = response.json()
if not data:
print("No more data. Ending ID collection.")
break
ids = [str(item["id"]) for item in data if "id" in item]
all_ids.extend(ids)
print(f"Found {len(ids)} IDs on page {page}")
if debug: # stop after 1 page in debug mode
break
time.sleep(0.2) # polite delay
page += 1
# Save IDs to file
id_filename = f"{username}_ids.txt"
with open(id_filename, "w") as f:
f.write("\n".join(all_ids))
print(f"Saved {len(all_ids)} IDs to {id_filename}")
return all_ids
def process_ids(ids, username):
"""Fetch tags for each ID and count occurrences."""
post_url = "https://danbooru.donmai.us/posts/{id}.json"
general_counter = Counter()
copyright_counter = Counter()
character_counter = Counter()
artist_counter = Counter()
for idx, post_id in enumerate(ids, start=1):
url = post_url.format(id=post_id)
print(f"[{idx}/{len(ids)}] Fetching post {post_id}...")
response = requests.get(url)
response.raise_for_status()
post_data = response.json()
# General tags
if "tag_string_general" in post_data and post_data["tag_string_general"]:
general_counter.update(post_data["tag_string_general"].split())
# Copyright tags
if "tag_string_copyright" in post_data and post_data["tag_string_copyright"]:
copyright_counter.update(post_data["tag_string_copyright"].split())
# Character tags
if "tag_string_character" in post_data and post_data["tag_string_character"]:
character_counter.update(post_data["tag_string_character"].split())
# Artist tags
if "tag_string_artist" in post_data and post_data["tag_string_artist"]:
artist_counter.update(post_data["tag_string_artist"].split())
time.sleep(0.2) # polite delay
# Save results to separate files
save_counter(general_counter, f"{username}_general_tags.txt", "General Tags")
save_counter(copyright_counter, f"{username}_copyright_tags.txt", "Copyright Tags")
save_counter(character_counter, f"{username}_character_tags.txt", "Character Tags")
save_counter(artist_counter, f"{username}_artist_tags.txt", "Artist Tags")
def save_counter(counter, filename, label):
"""Save counter results to a file and print them."""
print(f"\n=== {label} ===")
with open(filename, "w") as f:
for tag, count in counter.most_common():
print(f"{tag}: {count}")
f.write(f"{tag}: {count}\n")
print(f"Results saved to {filename}")
def main():
# Prompt user for username
username = input("Enter the Danbooru username: ")
# Ask if debug mode
debug_input = input("Enable debug mode (only 1 page)? [Y/N]: ").strip().lower()
debug = debug_input == "y"
# Ask if loading IDs from file
load_input = input("Load IDs from existing file instead of fetching? [Y/N]: ").strip().lower()
if load_input == "y":
id_filename = f"{username}_ids.txt"
if os.path.exists(id_filename):
with open(id_filename, "r") as f:
ids = [line.strip() for line in f if line.strip()]
print(f"Loaded {len(ids)} IDs from {id_filename}")
else:
print(f"No file {id_filename} found. Fetching IDs instead...")
ids = fetch_ids(username, debug)
else:
ids = fetch_ids(username, debug)
# Process IDs
process_ids(ids, username)
if __name__ == "__main__":
main()
Edit: Just realised I forgot the artists. And updated the table to be more compact and changed it into a Top 20.
Thanks for this. There are some surprises for me here, especially with artists. I don't remember uploading that much moonsorrow or nengoro, for example. No surprise on Stellive though. There's a lot of art of them and they're not popular here, so it's easy to find quality art.