Como copiar texto da tabela usando o titereiro em nodejs

Sep 29 2020

Estou tentando extrair o texto OTP do HTML onde está dentro de uma linha da tabela e não há seletor como div id ou classe. Apenas o estilo div está presente. Como copiar o texto disso.

estou a usar https://temp-mail.org/

Aqui está o XPATH do campo OTP

/html/body/main/div[1]/div/div[3]/div[2]/div/div[1]/div/div[2]/div[3]/div[2]/div/table/tbody/tr/td/div[2]/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[3]/td/div

Aqui está o Seletor

body > main > div.container > div > div.col-sm-12.col-md-12.col-lg-12.col-xl-8 > div.tm-content > div > div.inboxWarpMain > div > div.inbox-data-content > div.inbox-data-content-intro > div:nth-child(13) > div > table > tbody > tr > td > div:nth-child(2) > table > tbody > tr > td > div > table > tbody > tr > td > table > tbody > tr:nth-child(3) > td > div

Imagem da estrutura de código sendo exibida nas ferramentas de desenvolvimento

Respostas

theDavidBarton Sep 29 2020 at 16:32

Certifique-se sempre de não violar os Termos de Uso do serviço realmente copiado. Talvez você pudesse alcançar o resultado desejado se usasse sua API? (https://rapidapi.com/Privatix/api/temp-mail)

Se você tem certeza que deseja usar a automação do navegador e prosseguir com a recuperação da senha de uso único com o titereiro, então: você pode usar o page.$evalmétodo para recuperar o conteúdo de texto de qualquer elemento com um seletor válido.

Nota: o que você já copiou de devtools como seletor é na verdade um seletor , não é obrigatório incluir uma classe CSS ou id de elemento. É totalmente normal (mesmo que seja um pouco redundante).

Por exemplo:

const selector = 'body > main > div.container > div > div.col-sm-12.col-md-12.col-lg-12.col-xl-8 > div.tm-content > div > div.inboxWarpMain > div > div.inbox-data-content > div.inbox-data-content-intro > div:nth-child(13) > div > table > tbody > tr > td > div:nth-child(2) > table > tbody > tr > td > div > table > tbody > tr > td > table > tbody > tr:nth-child(3) > td > div'

const text = await page.$eval(selector, el => el.innerText)
console.log(text)

Resultado:

233-552

Editar

Caso haja mais de um elemento com o qual o seletor possa corresponder, você pode usar document.querySelectorAllabordagens como $$evalou $$então selecionar o elemento no primeiro índice [0].

Neste caso de uso exato, o $é ocupado por jQuery, por isso entra em conflito com a $abreviação da API do Chrome para querySelector, veja aqui:

Soluções:

const selector = 'body > main > div.container > div > div.col-sm-12.col-md-12.col-lg-12.col-xl-8 > div.tm-content > div > div.inboxWarpMain > div > div.inbox-data-content > div.inbox-data-content-intro > div:nth-child(13) > div > table > tbody > tr > td > div:nth-child(2) > table > tbody > tr > td > div > table > tbody > tr > td > table > tbody > tr:nth-child(3) > td > div'

await page.waitFor(10000) // waitForTimeout since pptr 5.3.0

try {
  await page.waitForSelector(selector)
  const [text] = await page.$$eval(selector, elements => elements.map(el => el.innerText))
  console.log(text)
} catch (e) {
  console.error(e)
}
// alternate solution with page.evaluate:
try {
  const text = await page.evaluate(el => el.innerText, (await page.$$(selector))[0])
  console.log(text)
} catch (e) {
  console.error(e)
}