I am trying to programmatically access data in tables from the page https://rarity.tools/upcoming/ in javascript. Since the site loads through javascript, I've been using puppeteer. The site has multiple tables (4 total) and I would like to be able to reference each table and check how many rows they have.
I originally tried to use nth-of-type, but it seems the site I'm trying to receive data from doesn't structure their page in a way that would allow me to use nth-of-type or nth-child (please see: Accessing nth table and counting rows with pupeteer in javascript error: "failed to find element matching selector "table:nth-of-type(2) > tr"").
Instead, I'm trying to create a for loop to set the innerHTML of each table to its own variable and then analyze the HTML string based on the index. The following returns the correct value if I hardcode the number:
console.log(table_html)
let table_html = await page.evaluate(
() => document.querySelectorAll('table')[2].innerHTML
)
However, as soon as I set it to a loop:
for (let j = 0; j < numTables; j++) {
let table_html = await page.evaluate(
(j) => document.querySelectorAll('table')[j].innerHTML
)
console.log(table_html)
}
I receive the error:
Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'innerHTML') at puppeteer_evaluation_script:1:46 at ExecutionContext._evaluateInternal (C:\Users\kylel\Desktop\NFTSorter_IsolatedJS\node_modules\puppeteer\lib\cjs
puppeteer\common\ExecutionContext.js:221:19) at processTicksAndRejections (internal/process/task_queues.js:95:5) at async ExecutionContext.evaluate (C:\Users\kylel\Desktop\NFTSorter_IsolatedJS\node_modules\puppeteer\lib\cjs\pup peteer\common\ExecutionContext.js:110:16) at async fetch (C:\Users\kylel\Desktop\NFTSorter_IsolatedJS\app.js:35:30)
All code:
const puppeteer = require('puppeteer');
let fetch = async () => {
try {
// Puppeteer initialization
const browser = await puppeteer.launch({ headless: true, defaultViewport: null });
const [page] = await browser.pages();
await page.goto('https://rarity.tools/upcoming/');
await page.waitForTimeout(2500) // Timeout so page can load actual content
const numTables = await page.$$eval('table', el => el.length) - 1;
for (let j = 0; j < numTables; j++) {
let table_html = await page.evaluate(
(j) => document.querySelectorAll('table')[j].innerHTML
)
console.log(table_html)
}
}
catch (error) {
console.log(error)
}
}
fetch();
How do I fix this for loop to allow me to run the document.querySelectorAll('table') for each table?
Additionally, if anyone has any insights about ways I could achieve what I'm looking to do (programmatically access the data from these tables based on a variable amount of tables using puppeteer) it'd be much appreciated! And any recommendations of what tools to use to analyze HTML in string form if I end up utilizing the method described here?
Thank you very much!