Node.js Puppeteer爬取Instagram用户页4-5次后要求登录问题求解
解决方案
触发限制的核心原因
- 现有代码每次调用都会启动全新浏览器实例,无任何登录态、Cookie留存,短时间内多次无身份标识的访问直接触发Instagram未登录用户的访问频次阈值
- 访问行为过于机械,无模拟真人的操作延迟、行为特征,被反爬策略识别为自动化工具
具体优化方案
1. 持久化登录态+复用浏览器实例
不要每次请求都销毁重启浏览器,首次完成账号登录后将Cookie存储到本地,后续启动直接读取本地Cookie跳过登录步骤,也可以直接复用同一个浏览器实例处理多批次请求,减少冷启动带来的特征聚集。
2. 增加模拟真人行为特征
页面跳转、元素操作之间增加1-5秒的随机延迟,避免机械固定的操作节奏;可以加入随机滚动、鼠标移动等模拟操作,降低被反爬识别的概率。
3. 控制请求频率+IP轮换
单账号控制请求间隔不低于10秒,单日请求总量不超过200次;如果需要大规模爬取,搭配代理IP池做IP轮换,避免单个IP请求量过高被封禁。
4. 移除自动化工具特征
启动浏览器时添加参数屏蔽Puppeteer的自动化标识,避免被Instagram前端脚本识别为爬虫。
优化后代码示例
const puppeteer = require("puppeteer"); const fs = require("fs/promises"); const path = require("path"); // 本地Cookie存储路径 const COOKIE_PATH = path.join(__dirname, "ig_cookies.json"); let browser = null; // 初始化浏览器,复用实例 const initBrowser = async () => { if (browser) return browser; browser = await puppeteer.launch({ headless: false, ignoreHTTPSErrors: true, args: [ "--disable-blink-features=AutomationControlled", // 移除自动化标识 "--no-sandbox", "--disable-setuid-sandbox" ] }); // 读取本地已有Cookie try { const cookies = JSON.parse(await fs.readFile(COOKIE_PATH, "utf-8")); const page = await browser.newPage(); await page.setCookie(...cookies); await page.close(); } catch (e) { // 无本地Cookie则走首次登录流程 await firstLogin(); } return browser; }; // 首次登录逻辑,完成后保存Cookie const firstLogin = async () => { const page = await browser.newPage(); await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"); await page.goto("https://www.instagram.de/accounts/login/", {waitUntil: 'networkidle2'}); // 等待手动输入账号密码完成登录/人机验证,也可自行编写自动填充逻辑 await page.waitForNavigation({waitUntil: 'networkidle2', timeout: 0}); // 登录成功后保存Cookie到本地 const cookies = await page.cookies(); await fs.writeFile(COOKIE_PATH, JSON.stringify(cookies, null, 2)); await page.close(); }; const verification = async username => { try { const browser = await initBrowser(); const page = await browser.newPage(); await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"); // 随机延迟2-5秒再访问 await page.waitForTimeout(Math.floor(Math.random() * 3000 + 2000)); await page.goto(`https://www.instagram.de/${username}`, {waitUntil: 'networkidle2', timeout: 0, ignoreHTTPSErrors: true}); // 随机等待1-3秒再读取元素 await page.waitForTimeout(Math.floor(Math.random() * 2000 + 1000)); const d = await page.waitForSelector(".-vDIg > span", {timeout: 10000}); const value = await d.evaluate(el => el.textContent); await page.close(); console.log(value); console.log("-- bingo --"); } catch (e) { console.log("请求出错", e); } }; // 程序退出时关闭浏览器 process.on("beforeExit", async () => { if (browser) await browser.close(); }); module.exports = verification;
注意事项
- Instagram的前端类名会不定期更新,若选择器失效需要重新查询对应简介元素的最新选择器
- 尽量不要使用新注册的账号爬取,新号风控更严格,容易被直接封禁
- 若遇到人机验证,暂停请求1-2小时后再操作,不要高频触发验证
内容的提问来源于stack exchange,提问作者Datastores11
相关产品推荐
相关产品推荐

