Estoy escribiendo este código para raspar una página web. Necesito obtener información específica del sitio web y hay mucha información necesaria para raspar.
El código que escribo funciona, pero cuando lo hago repetidamente, encuentra un error en algunas de las líneas, por ejemplo, la línea 20, la línea 24.
A continuación se muestra el código
const browser = await puppeteer.launch() const page = await browser.newPage(); await page.goto("https://startupjobs.asia/job/search?q=&job-list-dpl-page=1", {timeout: 3000000}) const b = (await page.$x("/html/body/div[1]/div[3]/div[1]/div/div[1]/ul/li[1]/div/div[1]/div/h5/a"))[0] b.click() //const elm = await page.$('//*[@id="suj-single-jobdetail-wrapper"]/div[1]/div[1]/h5'); //const text = await page.evaluate(elm => elm.textContent, elm[0]); const [el1] = await page.$x('//*[@id="suj-single-jobdetail-wrapper"]/div[1]/div[1]/h5'); const job_name = await (await el1.getProperty('textContent')).jsonValue(); const [el2] = await page.$x('//*[@id="suj-single-jobdetail-wrapper"]/div[1]/div[2]/div/h6[1]/a'); const company = await (await el2.getProperty('textContent')).jsonValue(); const [el3] = await page.$x('/html/body/div[1]/div[3]/div[2]/div[2]/div[1]/div[2]/div[1]/div[3]/p'); const job_type= await (await el3.getProperty('textContent')).jsonValue(); const [el4] = await page.$x('/html/body/div[1]/div[3]/div[2]/div[2]/div[1]/div[2]/div[1]/div[1]/p'); const salary = await (await el4.getProperty('textContent')).jsonValue(); const [el5] = await page.$x('/html/body/div[1]/div[3]/div[2]/div[2]/div[1]/div[2]/div[1]/div[4]/p'); const skills = await (await el5.getProperty('textContent')).jsonValue();
Hay como 13 datos que necesito raspar.
El error que tengo es
const salario = await (await el4.getProperty('textContent')).jsonValue(); TypeError: no se pueden leer las propiedades de undefined (leyendo 'getProperty')
La solución rápida sería verificar si el ElementHandle desestructurado realmente existe antes de intentar llamar a getProperty
, por ejemplo:
const [el4] = await page.$x('/html/body/div[1]/div[3]/div[2]/div[2]/div[1]/div[2]/div[1]/div[1]/p'); const salary = !el4 ? 'Not Found' : await (await el4.getProperty('textContent')).jsonValue();
Un guión menos repetitivo se vería más como:
const elementsToFind = [ { xpath: '//*[@id="suj-single-jobdetail-wrapper"]/div[1]/div[1]/h5', propName: 'job_name' }, { xpath: '//*[@id="suj-single-jobdetail-wrapper"]/div[1]/div[2]/div/h6[1]/a', propName: 'company' }, // ... ]; const results = {}; for (const { xpath, propName } of elementsToFind) { const [el] = await page.$x(xpath); results[propName] = !el ? 'Not Found' : await (await el.getProperty('textContent')).jsonValue(); }
Y luego iterar a través del objeto de results
.