在这篇文章中,我们将看看如何使用Puppeteer来自动提交表单。Puppeteer是一个开源的Node库,它提供了一个高水平的API,通过DevTools协议控制基于Chrome或Chromium的浏览器。你可以用Chrome浏览器执行的每一项任务都可以用Puppeteer自动完成。这使得Puppeteer成为网络爬取和测试自动化的理想工具。在这篇文章中,我们将介绍关于用Puppeteer实现表单提交自动化的所有知识。我们将讨论
- 自动提交表格
- 使用Puppeteer选择器来定位表单输入
- 提交带有附件的表格
开始使用Puppeteer
在本节中,我们将对项目进行设置。如上所述,Puppeteer是一个node库。所以我们可以简单地用npm install
或yarn add
命令将其添加到我们的node项目中。让我们开始创建一个新的文件夹。
# create a new folder and navigate inside it mkdir form_demo cd form_demo
在我们的新项目文件夹中,我们可以通过运行以下命令初始化一个新的Node项目。
注意:我将在这个演示中使用
npm
。如果你喜欢的话,可以随意使用yarn
。
npm init --yes
一旦项目创建完毕,我们将安装Puppeteer。
npm i puppeteer --save
一旦软件包安装完毕,我们就可以创建一个名为index.js的新文件。这将是我们的主脚本。为了确保一切按预期工作,让我们用Puppeteer创建一个简单的自动化脚本并运行它:
const puppeteer = require('puppeteer'); async function main() { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://www.dailiservers.com/'); await page.waitForTimeout(5000); // wait for 5 seconds await browser.close(); } main();
在上面的脚本中,我们正在创建一个新的无头浏览器的实例。我们给出的指令是访问我们的dailiservers.com主页,等待5秒钟,然后简单地关闭浏览器。请注意,在第4行,我们将无头
选项设置为假
。我们这样做是为了让我们能直观地观察到浏览器打开网页和关闭的情况。
用node index.js
命令运行该脚本。我们将看到页面打开,5秒后自动关闭。
自动提交表格
我们验证了Puppeteer的安装,并按预期工作。现在我们可以继续进行我们的第一个表单提交。第一个例子将是非常简单的。我们将浏览yelp.com网站,并搜索加拿大多伦多附近的比萨外卖。
首先让我们访问一下yelp.com。
如果我们在Chrome浏览器中打开我们的开发工具并开始检查网页,我们可以看到查找输入有一个名为find_desc
的ID。我们还可以看到,附近的输入有一个ID叫dropperText_Mast
,搜索按钮有一个ID叫header-search-submit
。我们可以使用这些信息来编写我们的自动化脚本。
const puppeteer = require('puppeteer'); async function main() { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://www.yelp.com/'); await page.type('#find_desc', 'Pizza Delivery'); await page.type('#dropperText_Mast', 'Toronto, ON'); await page.click('#header-search-submit'); await page.waitForTimeout(5000); // wait for 5 seconds await browser.close(); } main();
在上面的脚本中,我们打开了一个新的浏览器实例。我们在第8行和第9行通过id来抓取输入。 在Puppeteer中,我们可以通过ID
来定位DOM
元素。我们使用Puppeteer的类型
函数来填充输入。type
函数的第一个参数是目标DOM
元素,第二个参数是我们希望Puppeteer为我们输入的字符串。 注意,我们也可以把类的名称作为第一个参数传递。例如,如果find_desc
是一个类而不是一个Id名称,我们可以这样做:
await page.type('.find_desc', 'Pizza Delivery');
在第10行,我们使用click
函数来模拟点击按钮。点击函数接受一个对应于DOM
节点的字符串标识符。
让我们运行这个脚本,看看它在这里的作用。
让我们来看看另一个例子,我们将通过名字来定位输入。在接下来的例子中,我将使用Github的登录页面。
如果我们打开谷歌开发工具并检查这里的表单,我们会看到这个表单的输入有名称
和id属性。请看下面的代码片段:
async function withInputName() { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://github.com/login'); await page.type('input[id=login_field]', 'John'); await page.type('input[name=password]', 'Password'); await page.evaluate(() => { document.querySelector('input[type=submit]').click(); }); } withInputName();
正如你所看到的,我们在这里使用了一种不同的语法类型。在第8行,我们通过id
定位输入,然后在第9行,通过名称
属性定位输入元素。正如你在第11行看到的,我们也可以通过类型来定位输入。请随意使用你觉得合适的语法,它们之间没有任何功能上的区别。
提交带有附件的表格
接下来,我们要看看如何上传文件的Puppeteer。我们将使用W3schools的这个演示表格来演示。让我们深入了解一下代码:
async function uploadFile() { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://www.w3schools.com/howto/howto_html_file_upload_button.asp'); const element = await page.$("input[type=file]"); await element.uploadFile('./myfile.pdf'); } uploadFile();
[文中代码源自Scrapingbee]
注意,我们是用Puppeteer提供的page.$
函数选择输入元素的。这将返回本地DOM
元素。这个元素能够访问所有的本地浏览器API。在下一行中,我们使用uploadFile
函数,从本地文件系统中附加一个文件。
当你运行该脚本时,你会看到本地路径的文件被附加到表单上,如下图所示:
今后的发展方向
Puppeteer是一个强大的工具。它的应用扩展到了自动提交表单。如果你想将Puppeteer用于你的网页爬取解决方案,我强烈建议你阅读他们的官方文档。我希望这篇文章内容丰富,让你对如何自动提交表单有一个广泛的了解。