Analyzing the Bing API
Bing's homepage displays a different high-quality background image daily. The image data can be accessed through Bing's JSON API endpoint. The API URL follows this pattern:
https://www.bing.com/HPImageArchive.aspx?format=js&n=1
The n parameter specifies the number of images to retrieve (maximum 7). The response contains an images aray with metadata including the url field, which provides the relative path to the actual image file.
To construct the full image URL, prepend https://www.bing.com to the url value from the JSON response.
Downloading a Single Image
import json
import os
import urllib.request
json_endpoint = "https://www.bing.com/HPImageArchive.aspx?format=js&n=1"
base_url = "https://www.bing.com"
target_folder = os.path.expanduser("~/Pictures/BingWallpaper")
if not os.path.exists(target_folder):
os.makedirs(target_folder)
response_file = os.path.join(target_folder, "bing_response.json")
urllib.request.urlretrieve(json_endpoint, response_file)
with open(response_file, "r", encoding="utf-8") as f:
data = json.load(f)
image_path = data["images"][0]["url"]
full_image_url = base_url + image_path
current_date = data["images"][0]["startdate"]
target_file = os.path.join(target_folder, f"{current_date}.jpg")
urllib.request.urlretrieve(full_image_url, target_file)
print(f"Downloaded: {target_file}")
Setting Wallpaper on Ubuntu
GNOME-based Ubuntu systems allow wallpaper changes via the command line using gsettings:
gsettings set org.gnome.desktop.background picture-uri "file:///home/username/Pictures/BingWallpaper/20230715.jpg"
Retrieving Multiple Images
To fetch multiple wallpapers (up to 7 days of history):
json_endpoint = "https://www.bing.com/HPImageArchive.aspx?format=js&n=7"
The response will contain 7 image entries in the images array.
Random Wallpaper Selection
import os
import random
wallpaper_dir = os.path.expanduser("~/Pictures/BingWallpaper")
all_images = [f for f in os.listdir(wallpaper_dir) if f.endswith('.jpg')]
random_image = random.choice(all_images)
full_path = os.path.join(wallpaper_dir, random_image)
Complete Automation Script
#!/usr/bin/env python3
import json
import os
import random
import urllib.request
import datetime
import subprocess
HOME_DIR = os.path.expandvars('$HOME')
WALLPAPER_DIR = os.path.join(HOME_DIR, "Pictures", "BingWallpaper")
CONFIG_DIR = os.path.join(HOME_DIR, ".config", "bing_wallpaper")
MAX_IMAGES = 7
KEEP_DAYS = 30
def ensure_directories():
for directory in [WALLPAPER_DIR, CONFIG_DIR]:
if not os.path.exists(directory):
os.makedirs(directory)
def fetch_image_metadata():
endpoint = f"https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n={MAX_IMAGES}"
cache_file = os.path.join(WALLPAPER_DIR, ".metadata.json")
urllib.request.urlretrieve(endpoint, cache_file)
with open(cache_file, "r", encoding="utf-8") as f:
return json.load(f)
def download_images(metadata):
base_url = "https://www.bing.com"
downloaded = []
for img in metadata["images"]:
img_url = base_url + img["url"]
img_name = img["startdate"] + ".jpg"
save_path = os.path.join(WALLPAPER_DIR, img_name)
if not os.path.exists(save_path):
urllib.request.urlretrieve(img_url, save_path)
print(f"Downloaded: {img_name}")
downloaded.append(save_path)
return downloaded
def set_random_wallpaper():
available = [f for f in os.listdir(WALLPAPER_DIR) if f.endswith('.jpg')]
if not available:
print("No wallpapers available")
return
selected = random.choice(available)
full_path = os.path.join(WALLPAPER_DIR, selected)
uri = f"file://{full_path}"
subprocess.run([
"gsettings", "set",
"org.gnome.desktop.background", "picture-uri",
uri
])
print(f"Wallpaper set to: {selected}")
def cleanup_old_images():
cutoff = datetime.datetime.now() - datetime.timedelta(days=KEEP_DAYS)
cutoff_str = cutoff.strftime('%Y%m%d')
for filename in os.listdir(WALLPAPER_DIR):
if filename.endswith('.jpg') and filename[:8] < cutoff_str:
file_path = os.path.join(WALLPAPER_DIR, filename)
os.remove(file_path)
print(f"Removed old wallpaper: {filename}")
def main():
ensure_directories()
metadata = fetch_image_metadata()
download_images(metadata)
set_random_wallpaper()
cleanup_old_images()
if __name__ == "__main__":
main()
Scheduling Automatic Updates
Use cron to run the script automatically:
crontab -e
Add the following line to execute the script every 6 hours:
0 */6 * * * /usr/bin/python3 /path/to/bing_wallpaper.py
Key Points
- The Bing API returns up to 7 recent images, identified by their
startdate - Image filenames follow the YYYYMMDD format
- The gsettings command requires the full file:// URI scheme
- Automatic cleanup prevents storage bloat from accumulating old images