Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何单击所有元素并等待每个元素完成AJAX请求以获取数据?(AJAX每次都加载在同一个元素中)_Javascript_Node.js_Puppeteer - Fatal编程技术网

Javascript 如何单击所有元素并等待每个元素完成AJAX请求以获取数据?(AJAX每次都加载在同一个元素中)

Javascript 如何单击所有元素并等待每个元素完成AJAX请求以获取数据?(AJAX每次都加载在同一个元素中),javascript,node.js,puppeteer,Javascript,Node.js,Puppeteer,情况: const puppeteer = require('puppeteer'); let scrape = async () => { const browser = await puppeteer.launch({headless: false}); const page = await browser.newPage(); await page.goto('https://website.com'); await page.setViewpor

情况:

const puppeteer = require('puppeteer');

let scrape = async () => {
    const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();

    await page.goto('https://website.com');
    await page.setViewport({width: ..., height: ...});

    const result = await page.evaluate(() => {
        let data = []; 
        let elements = document.querySelector('.class1').querySelectorAll('.class2'); 

        for (var element of elements){
            page.click(element);
            page.waitFor(2000);
            let 1 = document.querySelector('.class0').querySelector('.class3').getAttribute("data-1");
            let 2 = document.querySelector('.class0').querySelector('.class4').innerText;
            let 3 = document.querySelector('.class0').querySelector('.class5').innerText;
            let 4 = document.querySelector('.class0').querySelector('.class6').innerText;
            data.push({1: 1, 2: 2, 3: 3, 4: 4}); // Push an object with the data onto our array
        }

        return data; // Return our data array
    });

    browser.close();
    return result; // Return the data
};

scrape().then((value) => {
    console.log(value); // Success!
});
我现在正在学习用木偶演员刮

出于某种原因,我当前的代码会给我以下错误:

“未处理的PromisejectionWarning:错误:评估失败:引用错误:未定义页面”

编辑

问题是,当页面加载并单击每个项目时,数据不会被刮取,因为代码似乎不会在单击每个项目后等待加载

以下是代码应该执行的操作:

  • 加载网页(确定)

  • 单击每个项目(确定)

  • 每次单击一个项目时,一些数据都会加载到左侧的div中,这就是我要刮取的数据。(目前未发生)

  • 为了实现这一点,我让代码在单击后等待2秒钟,以便加载数据。(目前未发生)


  • 问题:

    const puppeteer = require('puppeteer');
    
    let scrape = async () => {
        const browser = await puppeteer.launch({headless: false});
        const page = await browser.newPage();
    
        await page.goto('https://website.com');
        await page.setViewport({width: ..., height: ...});
    
        const result = await page.evaluate(() => {
            let data = []; 
            let elements = document.querySelector('.class1').querySelectorAll('.class2'); 
    
            for (var element of elements){
                page.click(element);
                page.waitFor(2000);
                let 1 = document.querySelector('.class0').querySelector('.class3').getAttribute("data-1");
                let 2 = document.querySelector('.class0').querySelector('.class4').innerText;
                let 3 = document.querySelector('.class0').querySelector('.class5').innerText;
                let 4 = document.querySelector('.class0').querySelector('.class6').innerText;
                data.push({1: 1, 2: 2, 3: 3, 4: 4}); // Push an object with the data onto our array
            }
    
            return data; // Return our data array
        });
    
        browser.close();
        return result; // Return the data
    };
    
    scrape().then((value) => {
        console.log(value); // Success!
    });
    
    我如何修复此问题并适当地刮取所述数据


    代码:

    const puppeteer = require('puppeteer');
    
    let scrape = async () => {
        const browser = await puppeteer.launch({headless: false});
        const page = await browser.newPage();
    
        await page.goto('https://website.com');
        await page.setViewport({width: ..., height: ...});
    
        const result = await page.evaluate(() => {
            let data = []; 
            let elements = document.querySelector('.class1').querySelectorAll('.class2'); 
    
            for (var element of elements){
                page.click(element);
                page.waitFor(2000);
                let 1 = document.querySelector('.class0').querySelector('.class3').getAttribute("data-1");
                let 2 = document.querySelector('.class0').querySelector('.class4').innerText;
                let 3 = document.querySelector('.class0').querySelector('.class5').innerText;
                let 4 = document.querySelector('.class0').querySelector('.class6').innerText;
                data.push({1: 1, 2: 2, 3: 3, 4: 4}); // Push an object with the data onto our array
            }
    
            return data; // Return our data array
        });
    
        browser.close();
        return result; // Return the data
    };
    
    scrape().then((value) => {
        console.log(value); // Success!
    });
    

    尝试更改此行:

    await page.goto('https://website.com');
    
    致:


    此代码存在一些问题:

    • 1
      2
      等都不是有效的标识符(不过我猜这只是示例)
    • .click()
      .waitFor()
      将返回承诺,您不必等待,但无论如何
    • 传递给
      evaluate
      的函数是在页面上下文中计算的,而不是在Node.JS代码中计算的,因此
      page
      不存在
    相反,您可以直接在函数中与页面交互,就像您已经做的那样:

    const puppeteer = require('puppeteer');
    
    let scrape = async () => {
        const browser = await puppeteer.launch({ headless: false });
        const page = await browser.newPage();
    
        await page.goto('https://website.com');
        await page.setViewport({ width: ..., height: ... });
    
        const result = await page.evaluate(async () => {
            const data = [];
            const elements = document.querySelector('.class1').querySelectorAll('.class2');
    
            for (const element of elements) {
                element.click();
                await new Promise((resolve) => setTimeout(resolve, 2000));
                const one = document.querySelector('.class0').querySelector('.class3').getAttribute("data-1");
                const two = document.querySelector('.class0').querySelector('.class4').innerText;
                const three = document.querySelector('.class0').querySelector('.class5').innerText;
                const four = document.querySelector('.class0').querySelector('.class6').innerText;
                data.push({ 1: 1, 2: 2, 3: 3, 4: 4 }); // Push an object with the data onto our array
            }
    
            return data; // Return our data array
        });
    
        browser.close();
        return result; // Return the data
    };
    
    scrape().then((value) => {
        console.log(value); // Success!
    });
    

    等待新承诺((resolve)=>setTimeout(resolve,2000));^^SyntaxError:await仅在异步函数中有效删除await会使代码正常工作,但它不会等待数据加载,因此它会单击每个项目,但会刮取空数据…您是否在已计算的函数上添加了
    async
    ?您需要
    wait
    等待两秒钟,否则它将进入下一步。或者,您可以使用normal
    setTimeout
    并将其余代码放入回调中。