Skip to content

Instantly share code, notes, and snippets.

@seoutopico
Last active September 12, 2025 06:43
Show Gist options
  • Select an option

  • Save seoutopico/580ac7874e7f4bbd0673739de0624d23 to your computer and use it in GitHub Desktop.

Select an option

Save seoutopico/580ac7874e7f4bbd0673739de0624d23 to your computer and use it in GitHub Desktop.
Google AI Overview Scraper Un bookmarklet que extrae de forma sencilla los títulos y URLs que aparecen en los AI Overviews de Google.

Bookmarklet: Extraer enlaces de panel Google

Este bookmarklet permite extraer los enlaces de los resultados en el panel lateral de Google (contenedor .mv7LYc) y:

  • Tomar solo un enlace por resultado (<li>).
  • Copiar automáticamente al portapapeles en formato de lista con guiones.
  • Mostrar un popup con los enlaces extraídos para visualizarlos o copiarlos otra vez.

Instalación

  1. Copia el código del bookmarklet (más abajo).
  2. Crea un marcador nuevo en tu navegador.
  3. En la URL del marcador pega todo el código.
  4. Dale un nombre, por ejemplo: Extraer enlaces.

Uso

  1. Haz una búsqueda en Google que muestre un panel lateral con enlaces (ej: listas de libros).

  2. Haz clic en el marcador Extraer enlaces.

  3. Se abrirá un popup con:

    • El listado de enlaces en formato:

      - Título — URL
      - Título — URL
      ...
      
    • Botón para cerrar.

    • Botón para copiar otra vez al portapapeles.


Código del bookmarklet

javascript:(()=>{const vis=e=>{if(!e)return false;if(e.closest('[aria-hidden="true"]'))return false;const r=e.getClientRects();return !!(e.offsetParent||r.length)};const rmParams=u=>{try{const url=new URL(u);['ved','usg','utm_source','utm_medium','utm_campaign','utm_term','utm_content','gclid','sqi','oq','aqs','sa','opi','source','rct'].forEach(k=>url.searchParams.delete(k));return url.toString()}catch{return u}};const clean=h=>{try{const u=new URL(h,location.href);if(u.pathname==='/url'){const p=u.searchParams.get('url')||u.searchParams.get('q');if(p)return rmParams(p)}return rmParams(u.toString())}catch{return h}};const panel=document.querySelector('.mv7LYc');if(!panel){alert('No se encontró el panel .mv7LYc');return}const lis=[...panel.querySelectorAll('ul[jsname="Z3saHd"]>li[jsname="XAYRPc"]')];const anchors=lis.map(li=>li.querySelector('a.KEVENd[href]')).filter(a=>a&&vis(a));if(!anchors.length){alert('No se encontraron enlaces visibles.');return}const seen=new Set();const lines=[];for(const a of anchors){const href=clean(a.href);if(seen.has(href))continue;seen.add(href);const title=(a.getAttribute('aria-label')||a.textContent||'').replace(/\s+/g,' ').trim()||'(sin título)';lines.push(`- ${title}${href}`)}const txt=lines.join('\n');const copy=()=>{if(navigator.clipboard&&isSecureContext){return navigator.clipboard.writeText(txt).catch(()=>Promise.reject())}return new Promise((res,rej)=>{const ta=document.createElement('textarea');ta.value=txt;document.body.appendChild(ta);ta.select();try{document.execCommand('copy');res()}catch(e){rej(e)}finally{ta.remove()}})};const showPopup=(copiedOK)=>{const id='__bookmarklet_popup_list__';document.getElementById(id)?.remove();const overlay=document.createElement('div');overlay.id=id;overlay.style.cssText='position:fixed;inset:0;z-index:2147483647;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;';const box=document.createElement('div');box.style.cssText='background:#fff;max-width:800px;width:min(90vw,800px);max-height:85vh;border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,.25);overflow:hidden;display:flex;flex-direction:column;';const head=document.createElement('div');head.style.cssText='padding:14px 16px;border-bottom:1px solid #eee;display:flex;gap:10px;align-items:center;justify-content:space-between;';const h=document.createElement('div');h.textContent='Enlaces extraídos';h.style.cssText='font-weight:600';const status=document.createElement('div');status.textContent=copiedOK?`Copiado (${lines.length}) al portapapeles.`:`Mostrando lista (${lines.length}).`;status.style.cssText='font-size:12px;color:#555;margin-left:auto;margin-right:12px;';const btnClose=document.createElement('button');btnClose.textContent='Cerrar';btnClose.style.cssText='border:0;background:#eee;padding:8px 12px;border-radius:8px;cursor:pointer';btnClose.onclick=()=>overlay.remove();head.append(h,status,btnClose);const area=document.createElement('textarea');area.value=txt;area.readOnly=true;area.style.cssText='border:0;resize:none;outline:none;padding:14px 16px;font:13px/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre;flex:1;min-height:200px';const foot=document.createElement('div');foot.style.cssText='padding:12px 16px;border-top:1px solid #eee;display:flex;gap:8px;justify-content:flex-end;';const btnCopy=document.createElement('button');btnCopy.textContent='Copiar otra vez';btnCopy.style.cssText='border:0;background:#111;color:#fff;padding:10px 14px;border-radius:8px;cursor:pointer';btnCopy.onclick=()=>{copy().then(()=>{status.textContent=`Copiado (${lines.length}) al portapapeles.`}).catch(()=>{status.textContent='No se pudo copiar automáticamente. Copia manualmente.'})};foot.append(btnCopy);box.append(head,area,foot);overlay.append(box);document.body.append(overlay)};copy().then(()=>showPopup(true)).catch(()=>showPopup(false))})();

Notas

  • Si Google cambia las clases, puede ser necesario actualizar el selector.
  • Si no se logra copiar automáticamente, puedes usar el textarea del popup para copiar manualmente.
  • Funciona en navegadores modernos (Chrome, Edge, Firefox).
javascript:(()=>{const vis=e=>{if(!e)return false;if(e.closest('[aria-hidden="true"]'))return false;const r=e.getClientRects();return !!(e.offsetParent||r.length)};const rmParams=u=>{try{const url=new URL(u);['ved','usg','utm_source','utm_medium','utm_campaign','utm_term','utm_content','gclid','sqi','oq','aqs','sa','opi','source','rct'].forEach(k=>url.searchParams.delete(k));return url.toString()}catch{return u}};const clean=h=>{try{const u=new URL(h,location.href);if(u.pathname==='/url'){const p=u.searchParams.get('url')||u.searchParams.get('q');if(p)return rmParams(p)}return rmParams(u.toString())}catch{return h}};const panel=document.querySelector('.mv7LYc');if(!panel){alert('No se encontró el panel .mv7LYc');return}const lis=[...panel.querySelectorAll('ul[jsname="Z3saHd"]>li[jsname="XAYRPc"]')];const anchors=lis.map(li=>li.querySelector('a.KEVENd[href]')).filter(a=>a&&vis(a));if(!anchors.length){alert('No se encontraron enlaces visibles.');return}const seen=new Set();const lines=[];for(const a of anchors){const href=clean(a.href);if(seen.has(href))continue;seen.add(href);const title=(a.getAttribute('aria-label')||a.textContent||'').replace(/\s+/g,' ').trim()||'(sin título)';lines.push(`- ${title} — ${href}`)}const txt=lines.join('\n');const copy=()=>{if(navigator.clipboard&&isSecureContext){return navigator.clipboard.writeText(txt).catch(()=>Promise.reject())}return new Promise((res,rej)=>{const ta=document.createElement('textarea');ta.value=txt;document.body.appendChild(ta);ta.select();try{document.execCommand('copy');res()}catch(e){rej(e)}finally{ta.remove()}})};const showPopup=(copiedOK)=>{const id='__bookmarklet_popup_list__';document.getElementById(id)?.remove();const overlay=document.createElement('div');overlay.id=id;overlay.style.cssText='position:fixed;inset:0;z-index:2147483647;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;';const box=document.createElement('div');box.style.cssText='background:#fff;max-width:800px;width:min(90vw,800px);max-height:85vh;border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,.25);overflow:hidden;display:flex;flex-direction:column;';const head=document.createElement('div');head.style.cssText='padding:14px 16px;border-bottom:1px solid #eee;display:flex;gap:10px;align-items:center;justify-content:space-between;';const h=document.createElement('div');h.textContent='Enlaces extraídos';h.style.cssText='font-weight:600';const status=document.createElement('div');status.textContent=copiedOK?`Copiado (${lines.length}) al portapapeles.`:`Mostrando lista (${lines.length}).`;status.style.cssText='font-size:12px;color:#555;margin-left:auto;margin-right:12px;';const btnClose=document.createElement('button');btnClose.textContent='Cerrar';btnClose.style.cssText='border:0;background:#eee;padding:8px 12px;border-radius:8px;cursor:pointer';btnClose.onclick=()=>overlay.remove();head.append(h,status,btnClose);const area=document.createElement('textarea');area.value=txt;area.readOnly=true;area.style.cssText='border:0;resize:none;outline:none;padding:14px 16px;font:13px/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;white-space:pre;flex:1;min-height:200px';const foot=document.createElement('div');foot.style.cssText='padding:12px 16px;border-top:1px solid #eee;display:flex;gap:8px;justify-content:flex-end;';const btnCopy=document.createElement('button');btnCopy.textContent='Copiar otra vez';btnCopy.style.cssText='border:0;background:#111;color:#fff;padding:10px 14px;border-radius:8px;cursor:pointer';btnCopy.onclick=()=>{copy().then(()=>{status.textContent=`Copiado (${lines.length}) al portapapeles.`}).catch(()=>{status.textContent='No se pudo copiar automáticamente. Copia manualmente.'})};foot.append(btnCopy);box.append(head,area,foot);overlay.append(box);document.body.append(overlay)};copy().then(()=>showPopup(true)).catch(()=>showPopup(false))})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment