Guarda una lista de deseados de Steam en una hoja de cálculo: posición, juego, precio actual, precio original, descuento, fecha en que se añadió y enlace a la tienda. Funciona con tu lista y con cualquier lista pública.
Funciona con tu lista (con sesión iniciada) y con cualquier lista pública. Ábrela y ejecuta el script.
// Responsive Muse · Steam Wishlist Exporter · v1.0 · 2026-10-22
// Saves a Steam wishlist (yours, or a friend's if it's public) to CSV or TXT: rank, game, price,
// discount, the date it was added and the store link. Handy to track sales in a spreadsheet or
// to share your list. Runs only on store.steampowered.com/wishlist. It reads the list the page
// already loaded and scrolls it to see every price. It makes no network requests of its own and
// never reads cookies, passwords or tokens.
(async () => {
const TOOL = 'Exportar lista de deseados de Steam';
const FORMAT = 'csv'; // 'csv' (Excel, Sheets) or 'txt' ("Game - link", one per line)
if (location.hostname !== 'store.steampowered.com' || !location.pathname.startsWith('/wishlist')) {
alert('Abre primero una lista de deseados, por ejemplo la tuya:\nhttps://store.steampowered.com/wishlist/');
return;
}
// A small box on the page shows progress and asks before changing anything,
// so you never need to read or edit the console.
const many = (n, word) => `${n} ${n === 1 ? word : ({ canal: 'canales', 'canción': 'canciones', 'publicación': 'publicaciones', 'elemento guardado': 'elementos guardados' })[word] || word + 's'}`; // 1 vídeo, 2 vídeos
const panel = (() => {
const box = document.createElement('div');
box.style.cssText = 'position:fixed;right:16px;bottom:16px;z-index:2147483647;width:340px;max-width:calc(100vw - 32px);' +
'background:#111318;color:#e6e8ee;font:14px/1.5 system-ui,sans-serif;border-radius:12px;padding:16px;' +
'box-shadow:0 8px 30px rgba(0,0,0,.4);text-align:left';
const head = document.createElement('strong');
head.textContent = TOOL;
const msg = document.createElement('p');
msg.style.cssText = 'margin:8px 0 12px;white-space:pre-line';
const row = document.createElement('div');
row.style.cssText = 'display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end';
box.append(head, msg, row);
document.body.append(box);
const button = (label, primary, onClick) => {
const b = document.createElement('button');
b.textContent = label;
b.style.cssText = 'font:600 14px system-ui,sans-serif;padding:8px 14px;border-radius:8px;cursor:pointer;' +
(primary ? 'background:#0f766e;color:#fff;border:1px solid #0f766e' : 'background:none;color:#e6e8ee;border:1px solid #3a3f4b');
b.onclick = onClick;
row.append(b);
};
return {
text(t) { msg.textContent = t; },
ask(t, yes) {
msg.textContent = t;
row.replaceChildren();
return new Promise(r => {
button('Cancelar', false, () => { row.replaceChildren(); r(false); });
button(yes, true, () => { row.replaceChildren(); r(true); });
});
},
stoppable(onStop) { row.replaceChildren(); button('Parar', false, onStop); },
actions(t, list) {
msg.textContent = t;
row.replaceChildren();
list.forEach(([label, primary, run]) => button(label, primary, run));
},
finish(t) { this.actions(t, [['Cerrar', true, () => box.remove()]]); },
close() { box.remove(); },
};
})();
// Offer the result as a downloaded file or as clipboard text (a real click, so it always works)
const deliver = (summary, body, file) => {
const save = () => {
const a = document.createElement('a');
a.href = URL.createObjectURL(new Blob([/\.csv$/.test(file) ? '\ufeff' + body : body], { type: 'text/plain;charset=utf-8' }));
a.download = file;
a.click();
setTimeout(() => URL.revokeObjectURL(a.href), 5000);
panel.text(`${summary}\nGuardado como ${file} (mira tu carpeta de Descargas).`);
};
const copy = () => navigator.clipboard.writeText(body)
.then(() => panel.text(`${summary}\nCopiado. Pégalo en una hoja de cálculo o en una nota.`))
.catch(() => panel.text(`${summary}\nEl navegador ha bloqueado el portapapeles: usa Descargar.`));
panel.actions(summary, [['Cerrar', false, () => panel.close()], ['Copiar', false, copy], ['Descargar', true, save]]);
};
const sleep = ms => new Promise(r => setTimeout(r, ms));
// 1. The full list (order, priority, date added) comes with the page itself
let order = [];
const names = new Map();
try {
const cache = JSON.parse(window.SSR.renderContext.queryData).queries;
order = cache.find(q => q.queryKey[0] === 'WishlistSortedFiltered')?.state.data?.items || [];
for (const q of cache) {
const d = q.queryKey[0] === 'StoreItem' && q.state.data;
if (d?.appid && d.name) names.set(d.appid, d.name);
}
} catch (e) { /* older page: we'll rely on what is on screen */ }
// 2. Prices are only on screen: scroll the list and read each row as it appears
const seen = new Map();
const isPrice = t => t.length < 20 && /\d/.test(t) && /[€$£¥₹₩₽₺₴]|zł|kr|R\$|CHF|USD|ARS|CDN|Free|Gratis/i.test(t);
const collect = () => {
for (const row of document.querySelectorAll('[data-index]')) {
const a = [...row.querySelectorAll('a[href*="/app/"]')].find(x => x.textContent.trim());
const appid = Number((a?.getAttribute('href').match(/\/app\/(\d+)/) || [])[1]);
if (!appid || seen.has(appid)) continue;
const leaves = [...row.querySelectorAll('div, span')].filter(x => !x.childElementCount)
.map(x => x.textContent.trim()).filter(Boolean);
const discount = leaves.find(t => /^-\d+%$/.test(t)) || '';
const prices = leaves.filter(isPrice);
seen.set(appid, {
name: a.textContent.trim(),
price: prices[prices.length - 1] || '',
original: discount ? prices[0] || '' : '',
discount,
});
}
};
let scroller = document.querySelector('[data-index]');
while (scroller && !(scroller.scrollHeight > scroller.clientHeight + 50 && /auto|scroll/.test(getComputedStyle(scroller).overflowY))) {
scroller = scroller.parentElement;
}
scroller = scroller || document.scrollingElement;
let stop = false;
panel.stoppable(() => { stop = true; });
scroller.scrollTo(0, 0);
await sleep(800);
let idle = 0;
while (idle < 4 && !stop) {
const before = seen.size;
collect();
scroller.scrollBy(0, scroller.clientHeight * 0.8);
await sleep(900);
idle = seen.size === before ? idle + 1 : 0;
panel.text(`Leyendo la lista… ${seen.size}${order.length ? ' de ' + order.length : ''} juegos`);
}
// 3. Merge: every game of the list, with the price when we saw it
const ids = order.length ? order.map(o => o.appid) : [...seen.keys()];
const meta = new Map(order.map(o => [o.appid, o]));
const list = ids.map((id, i) => {
const s = seen.get(id) || {};
const added = meta.get(id)?.date_added;
return {
rank: i + 1,
name: s.name || names.get(id) || '',
price: s.price || '',
original: s.original || '',
discount: s.discount || '',
added: added ? new Date(added * 1000).toISOString().slice(0, 10) : '',
url: `https://store.steampowered.com/app/${id}/`,
};
});
if (!list.length) {
panel.finish('No se han encontrado juegos. ¿La lista está vacía o es privada? Si no, puede que Steam haya cambiado su diseño: avísanos en responsive-muse.com.');
return 0;
}
// 4. Build the file and offer it
const cell = v => '"' + String(v).replace(/"/g, '""') + '"';
const body = FORMAT === 'txt'
? list.map(g => `${g.name} - ${g.url}`).join('\n')
: ['Posición,Juego,Precio,Precio original,Descuento,Añadido,URL de la tienda', ...list.map(g =>
[g.rank, g.name, g.price, g.original, g.discount, g.added, g.url].map(cell).join(','))].join('\n');
const owner = (document.title.match(/(?:of|de)\s+(.+)$/i) || [])[1] || 'steam';
deliver(`${stop ? 'Parado antes de terminar. ' : ''}Listo: ${many(list.length, 'juego')}.`, body, `wishlist-${owner.replace(/[\\/:*?"<>|\s]+/g, '_')}.${FORMAT}`);
return list.length;
})();
Marcador: arrastra el botón del medio a tu barra de marcadores, abre store.steampowered.com y pulsa el marcador. Ejecuta el mismo script con las opciones de arriba.
- No envía nada a ningún sitio. Sin fetch, XHR ni scripts externos. La única actividad de red es la de store.steampowered.com cargando tu lista.
- No toca tu sesión. No lee cookies, contraseñas, tokens ni el almacenamiento del navegador.
- Solo funciona en store.steampowered.com. En cualquier otra web se detiene antes de hacer nada.
- Corto y legible. 158 líneas comentadas, sin minificar ni ofuscar.
- Muestra su progreso en la página. Un pequeño recuadro te dice qué está haciendo y al final te ofrece Descargar o Copiar.
- El mismo código para todos. SHA-256 de la versión por defecto:
18842f5674625aa8…
Compruébalo tú mismo en 30 segundos
- Léelo: todas las líneas están arriba, con comentarios.
- Busca en el código
fetch,XMLHttpRequest,cookie,localStorageoeval. No aparece ninguna. - Abre la pestaña Red (Network) antes de ejecutarlo: solo verás peticiones a store.steampowered.com.
Cómo usarlo
- Abre tu lista de deseados (con sesión iniciada) o la lista pública de un amigo.
- Abre la consola: F12 o Ctrl+Mayús+J (Cmd+Opción+J en Mac). Si Chrome te lo pide, escribe
permitir pegar(oallow pastingsi lo tienes en inglés) y pulsa Enter. - Elige las opciones, copia el script, pégalo en la consola y pulsa Enter. Al terminar aparece un recuadro: pulsa Descargar (o Copiar).
Para qué sirve
- Seguir las rebajas: exporta antes y durante unas rebajas de Steam y compara las columnas de precio y descuento.
- Presupuesto: suma la columna de precio para ver cuánto cuesta hoy tu lista.
- Compartirla: manda el TXT («Juego – enlace») antes de tu cumpleaños.
Preguntas frecuentes
¿Por qué algunos juegos salen sin precio?
Esos juegos ya no se venden en Steam (retirados de la tienda), así que no tienen precio. Siguen en tu lista con su enlace.
¿Puedo exportar la lista de un amigo?
Sí, si su perfil y su lista son públicos, o visibles para ti como amigo. Abre su lista y ejecuta el script.
¿Sirve para seguir las rebajas?
Expórtala ahora y más adelante: las columnas de precio, precio original y descuento muestran qué ha cambiado. Los precios van en la moneda de tu tienda de Steam.
Más herramientas gratis
YouTube
8 herramientas- Vaciar Ver más tarde
- Anular todas las suscripciones
- Quitar todos los «me gusta»
- Exportar Ver más tarde
- Exportar publicaciones guardadas
- Borrar todos los comentarios
TikTok
1 herramienta- Exportar vídeos de un perfil
Amazon
2 herramientas- Exportar historial de pedidos
- Exportar lista de deseos
X / Twitter
3 herramientas- Exportar guardados
- Quitar todos los «me gusta»
- Borrar todos los guardados
Chats de IA
4 herramientas- Exportar chat de ChatGPT
- Exportar chat de Claude
- Exportar chat de Gemini
- Exportar hilo de Perplexity
Google Maps
1 herramienta- Exportar reseñas de Google Maps
Steam
1 herramienta- Exportar lista de deseados de Steam
Apple Music
1 herramienta- Exportar playlist de Apple Music
