Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

255
Views
Cómo obtener datos de DOM, procesarlos y luego enviarlos en Chrome Extension MV3

No sé cuál es la mejor manera de expresarlo, pero decidí hacer una publicación aquí ya que estuve buscando durante unos días y no pude encontrar una respuesta exacta a lo que quiero hacer.

Entonces, básicamente estoy tratando de desarrollar una extensión de Chrome simple para verificar si los usuarios de Reddit son bots o no. La extensión sería:

  • Obtenga todos los usuarios del hilo actual usando document.querySelectorAll ;
  • Obtener datos personales del usuario de reddit;
  • Comprobar qué usuarios son bots;
  • Agregue una etiqueta [BOT] a todos los bots identificados.

Al principio traté de hacer algo como esto en mi background.js :

 chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { if (changeInfo.status === 'complete'){ chrome.scripting.executeScript({ target: { tabId: tabId}, func: getAuthors, }, (authors) =>{ authors.forEach(element => { getAbout(element).then(about =>{ getComments(element).then(comments =>{ isBot(about,comments).then(response =>{ //ADD TAG }); }); }); }); }) } });

La función getAuthors puede acceder con éxito al documento y recuperar los datos, el problema ocurre cuando tengo que acceder nuevamente para agregar las etiquetas.

Almacenar una matriz de autores y pasarla a otro chrome.scripting.executeScript no funciona, ya que la ejecución no esperará a que finalice el primer chrome.scripting.executeScript y lo ejecutará de inmediato.

Intenté invertir la lógica y usar mensajes también, esta vez en mi contentScript.js :

 chrome.runtime.sendMessage('get-names', (names) => { console.log('received user data', names); names.forEach(element => { element.parentElement.appendChild(tag); }); });

Ahora tengo una forma de agregar las etiquetas, pero no puedo enviar los datos para procesarlos en primer lugar, ya que, hasta donde yo sé, solo puede enviar una carga útil en respuesta . si envío un mensaje desde mi background.js , termino cayendo en una situación similar con el scripting y su ejecución asíncrona.

¿Hay una forma fácil de hacer esto?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Si bien es posible implementar esta tarea mediante una secuencia de comandos en segundo plano, una solución mejor y más simple es hacer todo en la secuencia de comandos de contenido.

La secuencia de comandos de contenido puede realizar cambios en DOM inmediatamente y puede realizar una solicitud de red a la URL del sitio actual para obtener los detalles del usuario. Sin embargo, la solicitud de red será asíncrona; de lo contrario, introduciría retrasos desagradables en la carga de la página.

Aquí está el esquema general:

  1. El script de contenido se carga en document_start cuando DOM está vacío.
  2. Lee los datos previamente almacenados sobre los usuarios que ya verificó en el pasado. El mejor almacenamiento aquí sería el propio window.localStorage del sitio porque es síncrono y pertenece al mismo proceso de pestaña interno, por lo que es rápido de leer.
  3. Use MutationObserver para detectar los elementos <a> agregados mientras se carga la página y también después para admitir la nueva interfaz de usuario de reddit (construye la página dinámicamente) y varios scripts de usuario/extensiones que expanden automáticamente los hilos en la antigua interfaz de usuario de reddit.
  4. Para cada elemento coincidente, obtenga los datos almacenados en caché.
  5. Si está ausente, realice una solicitud de red, aplique el resultado, guárdelo en el almacenamiento.

manifiesto.json:

 { "content_scripts": [{ "matches": ["*://www.reddit.com/*", "*://old.reddit.com/*"], "js": ["content.js"], "css": ["content.css"], "run_at": "document_start" }],

contenido.css:

 a.is-bot::after { content: '[BOT]'; color: red; margin-left: .25em; }

contenido.js:

 const CLASS = 'is-bot'; const LS_KEY = 'b:'; const USER_URL = location.origin + '/user/'; const SEL = `a[href^="/user/"], a[href^="${USER_URL}"]`; const checkedElems = new WeakSet(); const promises = {}; new MutationObserver(onMutation) .observe(document, {subtree: true, childList: true}); function onMutation(mutations) { for (const {addedNodes} of mutations) { for (const n of addedNodes) { const toCheck = n.tagName === 'a' ? n.href.startsWith(USER_URL) && [n] : n.firstElementChild && n.querySelectorAll(SEL); for (const el of toCheck || []) { if (checkedElems.has(el)) continue; checkedElems.add(el); const name = el.href.slice(USER_URL.length); const isBot = localStorage[LS_KEY + name]; if (isBot === '1') { el.classList.add(CLASS); } else if (isBot !== '0') { (promises[name] || (promises[name] = checkUser(el, name))) .then(res => res && el.classList.add(CLASS)); } } } } } async function checkUser(el, name) { const isBot = await (await fetch(API_URL + name)).json(); localStorage[LS_KEY + name] = isBot ? '1' : '0'; delete promises[name]; return isBot; }
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!