I. Knowledge points

Puppeteer, Nodejs, VsCode

Two, installation environment

Install nodejs (v10.16.0Version)

Nodejs for Windows, nodejs for Mac

Install the VsCode editor

VsCode for Windows, VsCode for Mac

3. Create a project directory

1. Create a project folder

After nodejs and VsCode are installed, create a folder puppeteer-demo anywhere and open the folder with VsCode

2. VsCode opens the CLI

3. NPM init press Enter to generate package.json file

4. Install the project dependency package on the CLI terminal

NPM install CNPM -g // Download the required tool package. CNPM install Express Puppeteer chai --saveCopy the code

5. Create a startup file in the project folderentry.js

Const express = require(const express = require('express'); // puppeteer = require('puppeteer'); Const fs = require('fs'); Var chai = require('chai'); var expect = chai.expect; Var app = express(); //Router = express.router (); Router.get('/test'.function (req, res) {
    res.end('Router test success! \n');
});

app.use(Router);
app.listen(7878, function afterListen() {
    console.log('express running on http://localhost:7878');
});

Copy the code

6. Add the run script to package.json

"start": "node entry.js"

Enter the command NPM run start to start the service

7. Enter in the browserhttp://localhost:7878/testTest whether the service is successful

Four, a few chestnuts

1. Get web content

Router.get(router.get ('/demo1'.function(req, res) { ; (async () => {// Initialize the environment and open the page const browser = await puppeteer.launch() const page = await browser.newPage() await page.goto('https://juejin.cn', { waitUntil: 'networkidle2'}) const handles = await page.? ('li.nav-item div a')
        const btnHtmls = await page.$$eval('li.nav-item div a', options => options.map(option => option.innerHTML))
        await handles[btnHtmls.indexOf('front end')].click() // await page.waitForSelector('.content-box .info-box .title-row a'Const articleInfos = await page.$$eval('.content-box .info-box .title-row a', options => options.map(option => {
            return{innerHTML: option.html, href: option.href}})) // Add the capture to the top10.txt filelet content = articleInfos.slice(0, 10).map((info => {
            return `${info.innerHTML}\r\n${info.href}`
        }))
        await fs.writeFile('./top10.txt', content.join('\r\n\r\n'), {}, function (err) {
            if(err) { throw err; }}); // Close the browser await browser.close(); res.end('Router demo1 success!! \n')
    })();

});
Copy the code

Restart the service, the browser to http://localhost:7878/demo1 after the success of the operation, project directory will be generated need. TXT file

2. Simulate form input

// demo2: Baidu search for "puppeteer" and go to the puppeteer GitHub home page router.get ('/demo2'.function(req, res) { ; (async () => {try {// initialize the environment and open the page // headless:falseConst browser = await puppeteer.launch({headless:false })
            const page = await browser.newPage()
            await page.goto('https://www.baidu.com', { waitUntil: 'networkidle2' })

            await page.waitFor(1000)

            const elementHandle = await page.$('#kw')
            await elementHandle.type('puppeteer');
            await elementHandle.press('Enter'); Await page.waitfor (1000) // Await page.waitForSelector('.result h3.t a') // Find GitHub entry const handles = await page.? ('.result h3.t a')
            const items = await page.$$eval('.result h3.t a', options => options.map(option => option.innerHTML))
            let targetItemIdx = 0;
            for (let i = 0; i < items.length; i++) {
                if (items[i].indexOf('GitHub') > -1) {
                    targetItemIdx = i
                    break}} // click 'await handles' [targetItemIdx].click() res.end()'Router demo2 success!! \n')
        } catch (error) {
            res.end('Router demo2 fail!! \n')}}) (); });Copy the code

Restart the service, the browser to http://localhost:7878/demo2

3. Automate UI tests

// demo3: Automatic UI test, input different mobile phone number test results router.get ('/demo3'.function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8'}); (async () => {try {// initialize the environment and open the page const browser = await puppeteer.launch({headless:false })
                const page = await browser.newPage()
                await page.goto('https://www.mytijian.com/m/mt', { waitUntil: 'networkidle2'}) // Jump to the login page await page.waitForSelector('.login-link')
                await page.click('.login-link'// Type the phone number await page.waitForSelector('input[placeholder=" placeholder "])
                const elementHandle = await page.$('input[placeholder=" placeholder "])
                let { mobile } = req.query
                await elementHandle.type(mobile || '12333333333'WaitFor (500) const btnHandle = await page.$('.weui-cell__ft button.weui-vcode-btn') await btnhandle.click () // Check whether the returned result is properly await page.waitfor (500) expect(await page).$eval('.weui-toast__content-warning', node => node.innerText.trim())).to.equal('Captcha cannot be null')

                await browser.close()

                res.end('Router demo3 success!! \n')
            } catch (error) {
                console.log(error)
                res.end(error.toString())
            }
        })();

});
Copy the code

Restart the service, the browser to http://localhost:7878/demo3? Mobile =12333333333, you can see the test results

4. Generate screen shots and PDF files of the page

// Demo4: Generate a screenshot of the page and PDF file router.get ('/demo4'.function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8'}); (async () => {try {// initialize the environment and open the page const browser = await puppeteer.launch({args: ['--no-sandbox'.'--disable-setuid-sandbox'] })
                const page = await browser.newPage()
                await page.goto('http://www.dili360.com'// wait for the page to finish loading await page.waitForSelector('.tags .right') // Hide item navigation await page.addStyleTag({content:'.part-two { display: none; } '}) // Const elementHandle = await page.$('.tags .right')
                await elementHandle.screenshot({path: 'screenshot.png'}) / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - / / open the CCTV network, generating PDF await page. Goto ('http://news.cctv.com')
                await page.pdf({
                    path: 'news.pdf',
                    format: 'A4'.printBackground: true,
                    margin: {
                      top: '15mm',
                      bottom: '15mm'
                    },
                    displayHeaderFooter: true,
                    footerTemplate: '
      
/
'
, headerTemplate: '
I"m header!
'
}); await browser.close() res.end('Router demo4 success!! \n') } catch (error) { res.end(error.toString()) } })(); }); Copy the code

After the restart the service, the browser to http://localhost:7878/demo4, the execution, can see screenshot of the new generation. The PNG and news. PDF

Complete code github

Const express = require(const express = require('express'); // puppeteer = require('puppeteer'); Const fs = require('fs'); Var chai = require('chai'); var expect = chai.expect; Var app = express(); //Router = express.router (); Router.get('/test'.function (req, res) {
    res.end('Router test success! \n');
});

Router.get('/demo1'.function(req, res) { ; (async () => {// Initialize the environment and open the page const browser = await puppeteer.launch() const page = await browser.newPage() await page.goto('https://juejin.cn', { waitUntil: 'networkidle2'}) const handles = await page.? ('li.nav-item div a')
        const btnHtmls = await page.$$eval('li.nav-item div a', options => options.map(option => option.innerHTML))
        await handles[btnHtmls.indexOf('front end')].click() // await page.waitForSelector('.content-box .info-box .title-row a'Const articleInfos = await page.$$eval('.content-box .info-box .title-row a', options => options.map(option => {
            return{innerHTML: option.html, href: option.href}})) // Add the capture to the top10.txt filelet content = articleInfos.slice(0, 10).map((info => {
            return `${info.innerHTML}\r\n${info.href}`
        }))
        await fs.writeFile('./top10.txt', content.join('\r\n\r\n'), {}, function (err) {
            if(err) { throw err; }}); // Close the browser await browser.close(); res.end('Router demo1 success!! \n')}) (); }); // demo2: Baidu search for "puppeteer" and go to the puppeteer GitHub home page router.get ('/demo2'.function(req, res) { ; (async () => {try {// initialize the environment and open the page const browser = await puppeteer.launch({headless:false })
            const page = await browser.newPage()
            await page.goto('https://www.baidu.com', { waitUntil: 'networkidle2' })

            await page.waitFor(1000)

            const elementHandle = await page.$('#kw')
            await elementHandle.type('puppeteer');
            await elementHandle.press('Enter'); Await page.waitfor (1000) // Await page.waitForSelector('.result h3.t a') // Find GitHub entry const handles = await page.? ('.result h3.t a')
            const items = await page.$$eval('.result h3.t a', options => options.map(option => option.innerHTML))
            let targetItemIdx = 0;
            for (let i = 0; i < items.length; i++) {
                if (items[i].indexOf('GitHub') > -1) {
                    targetItemIdx = i
                    break}} // click 'await handles' [targetItemIdx].click() res.end()'Router demo2 success!! \n')
        } catch (error) {
            res.end('Router demo2 fail!! \n')}}) (); }); // demo3: Automatic UI test, input different mobile phone number test results router.get ('/demo3'.function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8'}); (async () => {try {// initialize the environment and open the page const browser = await puppeteer.launch({headless:false })
                const page = await browser.newPage()
                await page.goto('https://www.mytijian.com/m/mt', { waitUntil: 'networkidle2'}) // Jump to the login page await page.waitForSelector('.login-link')
                await page.click('.login-link'// Type the phone number await page.waitForSelector('input[placeholder=" placeholder "])
                const elementHandle = await page.$('input[placeholder=" placeholder "])
                let { mobile } = req.query
                await elementHandle.type(mobile || '12333333333'WaitFor (500) const btnHandle = await page.$('.weui-cell__ft button.weui-vcode-btn') await btnhandle.click () // Check whether the returned result is properly await page.waitfor (500) expect(await page).$eval('.weui-toast__content-warning', node => node.innerText.trim())).to.equal('Captcha cannot be null')

                await browser.close()

                res.end('Router demo3 success!! \n') } catch (error) { console.log(error) res.end(error.toString()) } })(); }); // Demo4: Generate a screenshot of the page and PDF file router.get ('/demo4'.function (req, res) {
    res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8'}); (async () => {try {// initialize the environment and open the page const browser = await puppeteer.launch({args: ['--no-sandbox'.'--disable-setuid-sandbox'] })
                const page = await browser.newPage()
                await page.goto('http://www.dili360.com'// wait for the page to finish loading await page.waitForSelector('.tags .right') // Hide item navigation await page.addStyleTag({content:'.part-two { display: none; } '}) // Const elementHandle = await page.$('.tags .right')
                await elementHandle.screenshot({path: 'screenshot.png'}) / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - / / open the CCTV network, generating PDF await page. Goto ('http://news.cctv.com')
                await page.pdf({
                    path: 'news.pdf',
                    format: 'A4'.printBackground: true,
                    margin: {
                      top: '15mm',
                      bottom: '15mm'
                    },
                    displayHeaderFooter: true,
                    footerTemplate: '
      
/
'
, headerTemplate: '
I"m header!
'
}); await browser.close() res.end('Router demo4 success!! \n') } catch (error) { res.end(error.toString()) } })(); }); app.use(Router); app.listen(7878, function afterListen() {     console.log('express running on http://localhost:7878'); }); Copy the code