如何使用 Puppeteer 创建刮板并提交表单
米赫内亚-奥克塔维安-马诺拉什(Mihnea-Octavian Manolache),2023 年 2 月 28 日

您在网络搜索时处理过 POST 请求吗?我相信你一定遇到过!我们大多数时候都要处理表单。这就是为什么今天我要谈谈如何使用Puppeteer 提交表单。如果你还不知道 puppeteer 是什么,别担心。一会儿你就会知道了。在此之前,请允许我为今天的文章设定一些期望。如果你跟随我走上我们的学习之路,今天你应该能够学到
- 什么是网络搜索中的 Puppeteer?
- 如何建立一个简单的 Puppeteer 项目
- Puppeteer 如何处理表单提交
话不多说,我们开始吧!
什么是 Puppeteer,为什么它对网络搜索很重要?
一般来说,网络搜刮指的是从各种服务器中自动提取数据的过程。在过去,一个简单的 HTTP 客户端就足以完成这项任务。但如今,网站越来越依赖 JavaScript。而传统的 HTTP 客户端无法呈现 JavaScript 文件。这就是 Puppeteer 发挥作用的地方。
Puppeteer 是一个 Node.js 库,可让您通过 DevTools 协议控制无头 Chrome 或 Chromium 浏览器。简而言之,它为 Chrome 浏览器的自动化提供了一个高级 API。
在网络搜刮方面,Puppeteer 可用于搜刮需要 JavaScript 渲染的网站。此外,它还可用于以类似人类的方式与网页进行交互。例如,点击按钮或填写表格。这使得它非常适合于使用反抓取技术的网站。
设置简单的 Puppeteer 项目
我相信,慢慢来才能更好地理解整个过程。在介绍如何使用 Puppeteer 提交表单之前,我们先来谈谈简单的 Puppeteer。在本节中,我将向你展示如何建立一个 Node 项目、安装 Puppeteer 并用它来刮取数据。所以,首先,让我们创建一个新文件夹,并在我们想要的集成开发环境中打开它。我更喜欢 Visual Studio Code,但你也可以随意使用。
你知道吗?
- 你可以通过输入 `mkdir` 命令,在终端 "编程 "创建一个新文件夹。
- 您可以使用 `npm init -y` 命令来设置节点项目并接受默认值
- 您可以使用 `touch` 命令创建新文件。
- 您还可以使用 `code .` 命令打开 VSCode。
如果你愿意,可以将这四种方法结合起来,像这样几秒钟就能完成一个项目:
~ " mkdir scraper && cd scraper && npm init -y && code .
在集成开发环境中,打开一个新终端(终端 > 新终端),然后安装 Puppeteer。在终端中键入 `npm i puppeteer --save`。另外,我喜欢使用 JS 模块而不是 CommonJS。在此查看两者的区别。如果你也想使用模块,打开 `package.json` 并在 JS 文件中添加 `"type":"模块"`到 JSON 对象中。

现在我们已经准备就绪,可以开始添加代码了。创建一个新的 `index.js` 文件并在集成开发环境中打开它。这次不需要在终端上打开,但作为提示,你可以使用 `touch` 命令。 现在让我们添加代码:
import puppeteer, { executablePath } from 'puppeteer'
const scraper = async (url) => {
const browser = await puppeteer.launch({
headless: false,
executablePath: executablePath(),
})
const page = await browser.newPage()
await page.goto(url)
const html = await page.content()
await browser.close()
return html
}
让我们看看我们在做什么:
- 我们将 Puppeteer 和 `executablePath` 导入我们的项目
- 我们要定义一个新函数,它接受一个 `url` 参数
- 我们正在使用 `puppeteer.launch` 启动一个新浏览器
a. 我们指定要让它运行 headfull
b. 我们正在使用 `executablePath` 获取 Chrome 浏览器路径 - 我们将打开一个新页面,并导航至 `url
- 我们把 `page.content()` 保存在一个常量中
- 我们关闭了浏览器实例
- 最后,我们将返回刚刚获取的页面的 `html` 输出结果
到目前为止,事情并不复杂。这是用 Node JS 和 Puppeteer 实现网络刮刀的最低限度。如果要运行代码,只需给 `scraper` 函数一个目标并记录其返回值即可:
console.log(await scraper('https://webscrapingapi.com/'))
但请记住,我们的目标是在提交表单时提取数据。这意味着我们必须想办法用 Puppeteer 提交表单。幸运的是,我以前做过,我知道这并不难。所以,让我们看看你也能做到这一点。
如何使用 Puppeteer 提交表格
将 Puppeteer 视为在特定网站上模仿人类行为的手段。我们人类如何提交表单?我们识别表单,填写表格,然后点击按钮。这与 Puppeteer 提交表单的逻辑相同。唯一不同的是我们如何执行这些操作。因为人类依靠的是感官。由于 puppeteer 是一款软件,我们将使用 puppeteer 的内置方法以编程方式完成这些操作,就像这样:
#1:使用 Puppeteer 提交简单表格
首先,我们需要将表单 "可视化"。在网站中,所有元素都集中在一个 HTML 块中,每个元素都有一个标识符。标识符通常由元素的 CSS 属性组成。但是,您可能会遇到没有这种选择器的网站。在这种情况下,你可以使用 xPaths。但这是另一个话题。让我们专注于在 Puppeteer 中使用 CSS 识别元素。
假设我们想在 Stack Overflow 上自动执行登录操作,请先了解一下背景情况。因此目标是https://stackoverflow.com/users/login。打开浏览器,导航到登录页面,然后打开 "开发工具"。你可以右键单击页面并选择 "检查"。你应该会看到类似这样的内容:

左侧是图形界面。右侧是 HTML 结构。仔细观察右侧,你会看到我们的表单。它主要由两个输入和一个按钮组成。这就是我们的三个目标元素。正如你所看到的,这三个元素的 CSS 标识都是 "id"。让我们把目前学到的内容转化为代码:
import puppeteer, { executablePath } from 'puppeteer'
const scraper = async (target) => {
const browser = await puppeteer.launch({
headless: false,
executablePath: executablePath(),
})
const page = await browser.newPage()
await page.goto(target.url,{waitUntil: 'networkidle0'})
await page.type(target.username.selector, target.username.value)
await page.type(target.password.selector, target.password.value)
await page.click(target.buttonSelector)
const html = await page.content()
await browser.close()
return html
}
为了保持其功能性和可重用性,我选择用一个对象取代函数参数。这个对象包括目标 URL、输入选择器和值,以及提交按钮的选择器。因此,要运行代码,只需创建一个新的 `TARGET` 对象来保存数据,并将其传递给您的 `scraper` 函数:
const TARGET = {
url: 'https://stackoverflow.com/users/login',
username: {
selector: 'input[id=email]',
value: '<YOUR_USERNAME>'
},
password: {
selector: 'input[id=password]',
value: '<YOUR_PASSWORD>'
},
buttonSelector: 'button[id=submit-button]'
}
console.log(await scraper(TARGET))
#2:使用 Puppeteer 上传文件
有时,网络自动化要求我们上传文件,而不是提交简单的表单。如果你遇到这样的任务,并需要在使用 Puppeteer 提交表单之前附加文件,你会希望使用 Puppeteer 的`uploadFile` 方法。为了保持简单,我建议你为这个操作创建一个新函数:
const upload = async (target) => {
const browser = await puppeteer.launch({
headless: false,
executablePath: executablePath(),
})
const page = await browser.newPage()
await page.goto(target.url,{waitUntil: 'networkidle0'})
const upload = await page.$(target.form.file)
await upload.uploadFile(target.file);
await page.click(target.form.submit)
await browser.close()
}
看看这次我是如何使用 `page.$` 来首先识别元素的。然后,我才调用只适用于 `ElementHandle` 类型的 `uploadFile` 方法。在参数方面,和之前一样,我使用一个对象将所有数据一次性传递给我的函数。如果你想测试脚本,只需添加以下代码并在终端运行 `node index.js`:
const TARGET = {
url: 'https://ps.uci.edu/~franklin/doc/file_upload.html',
form: {
file: 'input[type=file]',
submit: 'input[type=submit]'
} ,
file: './package.json'
}
upload(TARGET)
结论
综上所述,我认为使用 Puppeteer 提交表单非常简单。此外,我还发现,与其他产品相比,Puppeteer 能完全处理这一操作。基本上,用户要做的就是正确识别元素。
现在,我需要指出的是,现实世界中的搜刮器需要更多才能提高效率。大多数情况下,如果你 "滥用 "服务器,在短时间内提交过多表单,很可能会被阻止。 因此,如果你想自动完成表单提交过程,我建议你使用专业的搜索服务。在 Web Scraping API 中,我们提供发送 POST 和 PUT 请求的选项。
新闻和更新
订阅我们的时事通讯,了解最新的网络搜索指南和新闻。
We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

相关文章



学习如何使用 Golang 搜刮 HTML 表格以进行强大的数据提取。探索 HTML 表格的结构,并使用 Golang 的简洁性、并发性和强大的标准库构建网络刮擦工具。


