Javascript 如何在节点服务器上使用Puppeter并在前端HTML页面上获得结果?

Javascript 如何在节点服务器上使用Puppeter并在前端HTML页面上获得结果?,javascript,ajax,puppeteer,Javascript,Ajax,Puppeteer,我刚刚开始学习节点和木偶演员,所以原谅我提前成为一个傻瓜 我在index.html页面上有一个简单的表单,我希望它能够从运行Puppeter的节点服务器上的函数返回Instagram配置文件的图像。在下面的代码中有一个Index.HTML文件和一个Index.JS文件,在Index.HTML文件中,当单击按钮时,我只想通过AJAX请求调用服务器,传入用户名并在服务器上运行该函数,将结果返回到HTML文件,并将响应文本放入.images div(我可以分割结果并稍后呈现img标记) 我有几个问题:

我刚刚开始学习节点和木偶演员,所以原谅我提前成为一个傻瓜

我在index.html页面上有一个简单的表单,我希望它能够从运行Puppeter的节点服务器上的函数返回Instagram配置文件的图像。在下面的代码中有一个Index.HTML文件和一个Index.JS文件,在Index.HTML文件中,当单击按钮时,我只想通过AJAX请求调用服务器,传入用户名并在服务器上运行该函数,将结果返回到HTML文件,并将响应文本放入.images div(我可以分割结果并稍后呈现img标记)

我有几个问题:

1:我在VSC中运行带有liveserver插件的server.js,它在
http://127.0.0.1:5500/12_Puppeteer/12-scraping instagram/index.js
现在是端点了吗?那么我如何将用户名传递给服务器函数..在标题或url中?你能告诉我吗

2:在Index.HTML文件中的我的AJAX请求中,需要什么请求才能将用户名传递到服务器
scrapimages(username)
函数并获取返回的内容

这是我在index.html文件中尝试的内容:

       <body>
            <form>
                Username: <input type="text" id="username">&nbsp;&nbsp;
                <button id="clickMe" type="button" value="clickme" onclick="scrape(username.value);">
                Scrape Account Images</button>
            </form>

            <div class="images">
            </div>
        </body>

        <script>
            function scrape() {
                var xhttp = new XMLHttpRequest();
                xhttp.onreadystatechange = function() {
                    if (this.readyState == 4 && this.status == 200) {
                    document.querySelector(".images").innerHTML = this.responseText;
                    }
                };
                xhttp.open("GET", "http://127.0.0.1:5500/12_Puppeteer/12-scraping-instagram/index.js", true);
                xhttp.send();
            }


        </script>

您必须设置一个节点服务器,比如express或其他任何东西,然后通过POST/GET方法传递用户名,并使用node/express捕获用户名。然后您可以使用它运行Puppeter

例如,您的node.js/express服务器运行在端口8888上。 您的HTML如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form method="post">
        Username: <input type="text" name="username" id="username">&nbsp;&nbsp;
        <button id="clickMe" type="button" value="clickme" onclick="getImages(this.form.username.value)">
        Scrape Account Images</button>
    </form>

    <div id="scrapedimages"></div>
    <script>
        let imgArray

        const getImages = (username) => {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    document.querySelector('#scrapedimages').innerHTML = ''
                    imgArray = JSON.parse(this.responseText)
                    if ( imgArray.images.length > 0 ) {
                        imgArray.images.split(',').forEach( function (source) {
                            var image = document.createElement('img')
                            image.src = source
                            document.querySelector('#scrapedimages').appendChild(image)
                        })
                    }
                }
            };
            xhttp.open('GET', 'http://127.0.0.1:8888/instascraper/user/' + username, true);
            xhttp.send();
        }
    </script>
</body>
</html>

您必须设置一个节点服务器,比如express或其他任何东西,然后通过POST/GET方法传递用户名,并使用node/express捕获用户名。然后您可以使用它运行Puppeter

例如,您的node.js/express服务器运行在端口8888上。 您的HTML如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form method="post">
        Username: <input type="text" name="username" id="username">&nbsp;&nbsp;
        <button id="clickMe" type="button" value="clickme" onclick="getImages(this.form.username.value)">
        Scrape Account Images</button>
    </form>

    <div id="scrapedimages"></div>
    <script>
        let imgArray

        const getImages = (username) => {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    document.querySelector('#scrapedimages').innerHTML = ''
                    imgArray = JSON.parse(this.responseText)
                    if ( imgArray.images.length > 0 ) {
                        imgArray.images.split(',').forEach( function (source) {
                            var image = document.createElement('img')
                            image.src = source
                            document.querySelector('#scrapedimages').appendChild(image)
                        })
                    }
                }
            };
            xhttp.open('GET', 'http://127.0.0.1:8888/instascraper/user/' + username, true);
            xhttp.send();
        }
    </script>
</body>
</html>

非常感谢您给出如此广泛的答案!您为什么要将
[page]
放在方括号中?这只是现代浏览器和JS引擎支持的另一种声明性语法。它基本上是在
浏览器的数组中声明
页面
既然Puppeter chromium launch已经打开了一个新的选项卡,那么它就可以作为
页面使用了
非常感谢你给出了如此广泛的答案!你怎么会把
[页面]
在方括号中?这只是现代浏览器和JS引擎支持的另一种声明性语法。它基本上是在
browser.pages()数组中声明
页面
,因为Puppeter chromium已经打开了一个新选项卡,所以它可以用作
页面
const puppeteer = require('puppeteer')
const fs = require('fs-extra')
const express = require('express')
const app = express()
const port = 8888

const username = 'usernameInstaGram'
const password = 'passwordInstaGram'

;(async () => {

    app.get('/instascraper/user/:userID', async (request, response) => {
        const profile = request.params.userID
        const content = await scrapeImages (profile)
        response.set({
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Credentials': true,
            'Access-Control-Allow-Methods': 'POST, GET, PUT, DELETE, OPTIONS',
            'Access-Control-Allow-Headers': 'Content-Type',
            'Content-Type': 'text/plain'
        })

        response.send(content)
    })

    app.listen(port, () => {
        console.log(`Instascraper server listening on port ${port}!`)
    })

    const scrapeImages = async profile => {

        const browser = await puppeteer.launch()
        const [page] = await browser.pages()

        await page.goto('https://www.instagram.com/accounts/login/', {waitUntil: 'networkidle0', timeout: 0})

        await page.waitForSelector('[name=username]', {timeout: 0})
        await page.type('[name=username]', username)
        await page.waitForSelector('[name=password]', {timeout: 0})
        await page.type('[name=password]',password)

        await Promise.all([
            page.waitForNavigation(),
            page.click('[type=submit]')
        ])

        await page.waitForSelector('input[placeholder="Search"]', {timeout: 0})
        await page.goto(`https://www.instagram.com/${profile}`, {waitUntil: 'networkidle0', timeout: 0})

        await page.waitForSelector('body section > main > div > header ~ div ~ div > article a[href] img[srcset]', {visible:true, timeout: 0})

        const data = await page.evaluate( () => {
            const images = document.querySelectorAll('body section > main > div > header ~ div ~ div > article a[href] img[srcset]')
            const urls = Array.from(images).map(img => img.src )
            return urls;
        })

        await browser.close()

        return `{
            "images" : "${data}"
        }`
    }

})()