Descarga todos los audiolibros de tu biblioteca de Audible en una hoja de cálculo: título, autor, narrador, serie, si lo terminaste, progreso y enlace. Gratis, en tu navegador, desde cualquier tienda de Audible, sin instalar ninguna app ni dar tu contraseña a nadie.
Inicia sesión en tu tienda de Audible (audible.es, .com, .co.uk, .de, .fr…) en el navegador del ordenador y abre Biblioteca; luego ejecuta el script. Lee todas las páginas de tu biblioteca él solo.
// Responsive Muse · Audible Library Exporter · v1.0 · 2026-11-12
// Saves your whole Audible library to CSV or TXT: title, authors, narrators, series, status
// (finished, in progress, not started), progress, length or time left, ASIN and link. Audible has
// no export button. Runs only on your Library page of any Audible store (audible.com, .co.uk,
// .de, .es…). It reads your library page by page in a hidden frame of the same Audible site, like
// clicking "Next" yourself. It never sends anything anywhere and never reads cookies, passwords
// or tokens.
(async () => {
const TOOL = 'Exportar biblioteca de Audible';
const FORMAT = 'csv'; // 'csv' (Excel, Sheets, Goodreads, StoryGraph) or 'txt' ("Title - Author", one per line)
if (!/(^|\.)audible\.[a-z.]+$/.test(location.hostname) || !/^\/library\/titles/.test(location.pathname)) {
alert('Abre primero tu Biblioteca de Audible (con tu sesión iniciada), por ejemplo:\nhttps://www.audible.es/library/titles');
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', lugar: 'lugares' })[word] || word + 's'}`; // 1 vídeo, 2 vídeos
const panel = (() => {
const box = document.createElement('div');
box.style.cssText = 'display:block!important;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 clean = s => (s || '').replace(/\s+/g, ' ').trim();
const afterLabel = li => clean(li?.innerText || li?.textContent).replace(/^[^:]{1,30}:\s*/, ''); // "By: Name" → "Name"
// Load one page of your own library in a hidden frame and wait for it
const loadPage = path => new Promise(resolve => {
const frame = document.createElement('iframe');
frame.style.cssText = 'position:absolute;left:-9999px;width:1000px;height:800px';
const done = doc => { resolve(doc); setTimeout(() => frame.remove(), 0); };
frame.onload = () => done(frame.contentDocument);
setTimeout(() => done(null), 30000);
frame.src = new URL(path, location.origin).href;
document.body.appendChild(frame);
});
// Read the titles of one page
const readPage = doc => [...doc.querySelectorAll('[id^="adbl-library-content-row-"]')].map(row => {
const asin = row.id.split('-').pop();
const lis = [...row.querySelectorAll('li')];
const by = lis.find(li => li.querySelector('a[href*="/author/"], a[href*="searchAuthor"]'));
const narr = lis.find(li => li.querySelector('a[href*="searchNarrator"]'));
const finished = doc.getElementById('time-remaining-finished-' + asin);
const time = doc.getElementById('time-remaining-display-' + asin);
const meter = row.querySelector('[aria-valuenow]');
const timeText = time && !time.classList.contains('bc-pub-hidden') ? clean(time.textContent) : '';
const isFinished = finished && !finished.classList.contains('bc-pub-hidden');
const status = isFinished ? 'Terminado' : meter ? 'Empezado' : timeText ? 'Sin empezar' : '';
return {
asin,
title: clean(row.querySelector('.bc-size-headline3')?.textContent),
author: by ? afterLabel(by) : '',
narrator: narr ? afterLabel(narr) : '',
series: afterLabel(row.querySelector('li.seriesLabel')).replace(/\s+,/g, ','),
status,
progress: isFinished ? '100%' : meter ? meter.getAttribute('aria-valuenow') + '%' : status ? '0%' : '',
length: status === 'Sin empezar' ? timeText : '',
left: status === 'Empezado' ? timeText : '',
url: `${location.origin}/pd/${asin}`,
};
});
// 1. Every page of the library, 50 titles at a time
let stop = false;
panel.stoppable(() => { stop = true; });
const books = new Map();
for (let page = 1; page <= 200 && !stop; page++) {
panel.text(`Leyendo la página ${page}… ${many(books.size, 'título')} hasta ahora`);
const doc = await loadPage(`/library/titles?pageSize=50&page=${page}`);
if (!doc) break;
const before = books.size;
for (const b of readPage(doc)) if (!books.has(b.asin)) books.set(b.asin, b);
if (books.size === before) break; // past the last page Audible repeats it or shows none
}
const list = [...books.values()];
if (!list.length) {
panel.finish('No se han encontrado títulos. ¿Has iniciado sesión y es tu Biblioteca? Si es así, puede que Audible haya cambiado su diseño: avísanos en responsive-muse.com.');
return 0;
}
// 2. Build the file and offer it
const cell = v => '"' + String(v).replace(/"/g, '""') + '"';
const body = FORMAT === 'txt'
? list.map(b => b.author ? `${b.title} - ${b.author}` : b.title).join('\n')
: ['Título,Autor,Narrador,Serie,Estado,Progreso,Duración,Tiempo restante,ASIN,URL', ...list.map(b =>
[b.title, b.author, b.narrator, b.series, b.status, b.progress, b.length, b.left, b.asin, b.url].map(cell).join(','))].join('\n');
const done = list.filter(b => b.status === 'Terminado').length;
const reading = list.filter(b => b.status === 'Empezado').length;
deliver(`${stop ? 'Parado antes de terminar. ' : ''}Listo: ${many(list.length, 'título')}: ${done} terminados, ${reading} empezados.`, body,
`audible-library.${FORMAT}`);
return list.length;
})();
🛡️ ¿Chrome te dice «No pegues código…»? Es normal. Escribe allow pasting en la consola (o permitir pegar si tu Chrome está en español), pulsa Intro y vuelve a pegar. Solo hace falta una vez.
¿Por qué avisa Chrome?
Chrome lo muestra la primera vez que alguien pega algo en la consola, para proteger de estafas en las que te piden pegar código desconocido. Hace bien en avisar, y por eso este script está entero a la vista: 145 líneas comentadas que no envían nada a ningún sitio ni tocan tus contraseñas o cookies. Por qué es seguro.
¿Prefieres no usar la consola? Arrastra el botón Exportar biblioteca de Audible a tu barra de marcadores y haz clic en él estando en www.audible.com. Así no sale el aviso.
Marcador: arrastra el botón del medio a tu barra de marcadores, abre www.audible.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 www.audible.com cargando tu lista.
- No toca tu sesión. No lee cookies, contraseñas, tokens ni el almacenamiento del navegador.
- Solo funciona en www.audible.com. En cualquier otra web se detiene antes de hacer nada.
- Corto y legible. 145 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:
3bb9058fd2875810…
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 www.audible.com.
Cómo usarlo
- Inicia sesión en tu tienda de Audible en el navegador del ordenador y abre Biblioteca (por ejemplo
audible.es/library/titles). - Abre la consola: F12 o Ctrl+Mayús+J (Cmd+Opción+J en Mac). Si Chrome te lo pide, escribe
permitir pegary pulsa Enter. - Copia el script, pégalo en la consola y pulsa Enter. Lee todas las páginas de tu biblioteca, de 50 en 50 títulos, y te ofrece el archivo.
Qué obtienes
Una fila por título: título, autores, narradores, serie y número de libro, estado (terminado, empezado o sin empezar), porcentaje de progreso, duración (o tiempo restante en los que estás escuchando), ASIN y enlace. El recuadro también te dice cuántos libros has terminado. Elige TXT para una lista simple «Título – Autor».
¿Para qué exportar tu biblioteca de Audible?
Audible no permite exportar, así que una lista de tus audiolibros es la única forma de importarlos en Goodreads o StoryGraph, guardar una copia si te das de baja u ordenar tu biblioteca por lo que aún no has empezado. Las apps que lo hacen te piden entrar en Amazon a través de ellas; este script lee la página que ya tienes abierta y no envía nada a ningún sitio.
Preguntas frecuentes
¿Audible no tiene botón de exportar?
No. La web y la app solo te dejan ver tu biblioteca; no hay forma de descargarla como lista. Este script la guarda como hoja de cálculo en unos segundos.
¿Qué exporta?
Título, autores, narradores, serie y número de libro, estado (terminado, empezado o sin empezar), porcentaje de progreso, duración o tiempo restante, ASIN y enlace a cada libro. Los podcasts salen con su título y enlace.
¿Puedo importarlo en Goodreads o StoryGraph?
Sí. Los dos aceptan un CSV con título y autor: expórtalo en CSV y usa su página de importación, o usa el formato TXT («Título - Autor») para buscar los libros.
¿Funciona con bibliotecas grandes?
Sí. Lee tu biblioteca de 50 en 50 títulos, en un marco oculto de la misma web de Audible, hasta la última página.
¿Es seguro?
El script se ejecuta en tu propia pestaña de Audible, solo lee las páginas de tu Biblioteca y no envía nada a ningún sitio. Nunca toca tu contraseña ni cambia nada de tu cuenta.
