提升Web爬虫效率的秘密武器:Puppeteer选择器全攻略

引言

Puppeteer是一个强大的Node.js库,用于控制无头Chrome浏览器。它提供了丰富的API来进行网页自动化测试、抓取数据等操作。在使用Puppeteer时,选择器的使用至关重要,因为它们帮助我们定位和操作网页元素。本文将从基础到进阶,详细介绍Puppeteer中的选择器定位方法。


1. 基础选择器:page.$()page.$$()

1.1 page.$() - 查询单个元素

  • 基本格式:
javascript 复制代码
const element = await page.$(selector);
  • 用法示例:
javascript 复制代码
// 选择第一个按钮
const button = await page.$('button');
if (button) {
  await button.click();
}
  • 说明: 返回一个 ElementHandle,若没有找到则返回 null。

1.2 page.$$() - 查询多个元素

  • 基本格式:
javascript 复制代码
const elements = await page.$$(selector);
  • 用法示例:
javascript 复制代码
// 获取所有列表项
const items = await page.$$('.list-item');
for (const item of items) {
  const text = await page.evaluate(el => el.innerText, item);
  console.log(text);
}
  • 说明: 返回一个元素数组(ElementHandle[])。

2. 样式选择器:CSS Selector

2.1 介绍

CSS选择器是最常用的定位方式,兼容性广,表达能力强。

2.2 常用格式

css 复制代码
/* ID选择器 */
#id
/* 类名选择器 */
.className
/* 标签选择器 */
tag
/* 属性选择器 */
[attribute='value']
/* 后代选择器 */
parent descendant
/* 子选择器 */
parent > child

2.3 举例

javascript 复制代码
// 选择id为main的div
await page.click('#main');

// 选择所有class为button的元素
const buttons = await page.$$('.button');

// 选择表单中name为email的输入框
const emailInput = await page.$('input[name="email"]');

// 选择所有带data-*属性的元素
const dataAttrs = await page.$$('div[data-test]');

3. 使用 XPath:page.$x()

3.1 介绍

XPath 是一种路径表达式,擅长复杂结构的定位,特别适合含有动态内容或层级复杂的元素。

3.2 格式

javascript 复制代码
const [element] = await page.$x(xpathExpression);

3.3 举例

javascript 复制代码
// 通过文本内容定位某个按钮
const [button] = await page.$x("//button[contains(text(), '提交')]");
if (button) {
  await button.click();
}

// 定位第一个li元素
const [firstLi] = await page.$x("//ul/li[1]");

3.4 注意事项

  • 对于较新版本的Puppeteer,page.$x()已经移除,应该使用 page.locator()page.$() 替代 page.$x()

5. 高级技巧:等待元素、复合选择器和动态定位

5.1 等待元素出现

javascript 复制代码
await page.waitForSelector('.dynamic-element');
const dynamicEl = await page.$('.dynamic-element');

5.2 复合选择器

javascript 复制代码
// 选择某个父元素下的特定子元素
await page.$('.parent > .child');

5.3 动态选择

结合 page.waitForFunction(),等待满足条件的元素出现

javascript 复制代码
await page.waitForFunction(() => {
  return document.querySelectorAll('div.loaded').length > 0;
});

6. 实战案例:自动登录新浪

javascript 复制代码
const puppeteer = require('puppeteer');

async function start() {
  // 启动浏览器
  const browser = await puppeteer.launch({
    executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',  // 如果安装的时候跳过了下载浏览器,就需要指定本地已经下载的浏览器路径
    headless: false, // 不使用无头模式
    slowMo: 50, // 慢速模式,便于观察
    args: ['--window-size=1200,800'] // 设置窗口大小
  });

  // 打开新标签页
  const page = await browser.newPage();
  await page.goto('https://login.sina.com.cn/sso/signin?entry=wapsso&source=wapssosina&url=https%3A%2F%2Fmy.sina.cn%2F%3Fvt%3D4%26pos%3D108%26his%3D0%26m%3D31f000ddf803c79c1e40f7ddafbef70e');

  // 通过 css 定位
  const inputText = await page.$('input[type="text"]');
  await inputText.type('15010302001');
  const inputPwd = await page.$('input[type="password"]');
  await inputPwd.type('15010302001');

  const button = await page.$("button");
  await button.click();
  // setTimeout(async () => {
  //   await page.close();
  // }, 2000);
}

start();

结语

更多实用的功能和API请参考官方文档

如果你喜欢本教程,记得点赞+收藏!关注我获取更多JavaScript开发干货。

相关推荐
晓得迷路了2 小时前
栗子前端技术周刊第 116 期 - 2025 JS 状态调查结果、Babel 7.29.0、Vue Router 5...
前端·javascript·vue.js
How_doyou_do2 小时前
执行上下文、作用域、闭包 patch
javascript
叫我一声阿雷吧2 小时前
深入理解JavaScript作用域和闭包,解决变量访问问题
开发语言·javascript·ecmascript
顾北122 小时前
AI对话应用接口开发全解析:同步接口+SSE流式+智能体+前端对接
前端·人工智能
iDao技术魔方2 小时前
深入Vue 3响应式系统:为什么嵌套对象修改后界面不更新?
javascript·vue.js·ecmascript
历程里程碑2 小时前
普通数组-----除了自身以外数组的乘积
大数据·javascript·python·算法·elasticsearch·搜索引擎·flask
摸鱼的春哥2 小时前
春哥的Agent通关秘籍07:5分钟实现文件归类助手【实战】
前端·javascript·后端
喵手2 小时前
Python爬虫实战:采集菜谱网站的“分类/列表页”(例如“家常菜”或“烘焙”频道)数据,构建高可用的美食菜谱数据采集流水线(附CSV导出)!
爬虫·python·爬虫实战·零基础python爬虫教学·采集菜谱网站数据·家常菜或烘焙频道·构建高可用食谱数据采集系统
念念不忘 必有回响2 小时前
viepress:vue组件展示和源码功能
前端·javascript·vue.js
喵手2 小时前
Python爬虫实战:硬核解析 Google Chrome 官方更新日志(正则+文本清洗篇)(附 CSV 导出)!
爬虫·python·爬虫实战·零基础python爬虫教学·csv导出·监控谷歌版本发布历史·获取稳定版更新日志