Skip to content

Instantly share code, notes, and snippets.

@brunolm
Created May 21, 2026 23:55
Show Gist options
  • Select an option

  • Save brunolm/7c1a4a6d2a69edc247a7e1a0fd737045 to your computer and use it in GitHub Desktop.

Select an option

Save brunolm/7c1a4a6d2a69edc247a7e1a0fd737045 to your computer and use it in GitHub Desktop.
Google Photos bulk-select via DevTools
// Google Photos — bulk-select all photos by scrolling and clicking checkboxes.
//
// Usage:
// 1. Open https://photos.google.com in your browser.
// 2. Open DevTools (F12) and switch to the Console tab.
// 3. Paste this script and press Enter.
// 4. Wait for it to finish; verify the selection count in the toolbar.
// 5. Click the trash icon to delete (items go to Trash for 30 days).
//
// How it works:
// - Finds the inner scrollable container (Photos virtualizes its list).
// - Clicks day-header "Select all" checkboxes (efficient for multi-photo days).
// - Clicks individual photo checkboxes for single-photo days.
// - Scrolls and repeats until the bottom is reached.
//
// Caveats:
// - Destructive. Test on a small range first.
// - Google may cap very large selections; if Delete fails, do it in batches.
// - If selectors stop matching, inspect a checkbox and update R4HkWb / ckGgle.
(async () => {
const __my_sleep = __my_ms => new Promise(__my_r => setTimeout(__my_r, __my_ms));
const __my_scroller = (() => {
for (const __my_el of document.querySelectorAll('*')) {
if (__my_el.scrollHeight > __my_el.clientHeight + 100) {
const __my_s = getComputedStyle(__my_el);
if (__my_s.overflowY === 'auto' || __my_s.overflowY === 'scroll') return __my_el;
}
}
return document.scrollingElement;
})();
console.log('Scroller:', __my_scroller);
let __my_stable = 0, __my_clicked = 0, __my_lastScroll = -1;
while (__my_stable < 8) {
document.querySelectorAll('div.QcpS9c.R4HkWb[aria-checked="false"]').forEach(__my_cb => {
__my_cb.click(); __my_clicked++;
});
await __my_sleep(150);
document.querySelectorAll('div.QcpS9c.ckGgle[aria-checked="false"]').forEach(__my_cb => {
__my_cb.click(); __my_clicked++;
});
await __my_sleep(100);
const __my_before = __my_scroller.scrollTop;
__my_scroller.scrollBy({ top: __my_scroller.clientHeight * 0.7, behavior: 'instant' });
await __my_sleep(700);
const __my_after = __my_scroller.scrollTop;
if (__my_after === __my_lastScroll || __my_after === __my_before) __my_stable++; else __my_stable = 0;
__my_lastScroll = __my_after;
console.log(`clicked=${__my_clicked} scroll=${__my_after}/${__my_scroller.scrollHeight} stable=${__my_stable}`);
}
console.log(`Done. Clicked ${__my_clicked} checkboxes.`);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment