如何编写无需重复登录的网页爬虫?解决Puppeteer爬取CSFloat网站的登录验证问题
如何编写无需重复登录的网页爬虫?解决Puppeteer爬取CSFloat网站的登录验证问题
嘿,我来帮你搞定这个登录验证的麻烦!你遇到的核心问题是Puppeteer默认会启动一个全新的、干净的浏览器实例,完全不带你本地已有的Steam/CSFloat登录会话,所以每次都得重新走一遍Steam的验证流程,特别折腾。下面给你几个实用的解决方案,按优先级推荐:
方案一:复用本地Chrome的已登录会话(最推荐)
这个方法直接让Puppeteer调用你平时用的Chrome浏览器的用户数据目录——也就是保存了你所有登录状态、Cookie的地方,这样启动的浏览器就和你日常使用的一模一样,完全不用重新登录。
操作步骤:
- 先关掉你本地正在运行的所有Chrome窗口(同一个用户数据目录不能同时被两个Chrome实例占用,否则会报错)
- 找到你Chrome的用户数据目录:
- Windows:
C:\Users\你的用户名\AppData\Local\Google\Chrome\User Data - Mac:
~/Library/Application Support/Google/Chrome - Linux:
~/.config/google-chrome
- Windows:
- 修改你的Puppeteer启动代码,加上
userDataDir参数指定这个目录:
const puppeteer = require("puppeteer"); (async () => { // 替换成你自己的Chrome用户数据路径 const userDataDir = "C:\\Users\\你的用户名\\AppData\\Local\\Google\\Chrome\\User Data"; const browser = await puppeteer.launch({ headless: false, userDataDir: userDataDir, // 注意:如果你的Chrome版本和Puppeteer自带的Chromium版本差异大,可能要加executablePath指定本地Chrome路径 // executablePath: "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" // Windows示例 }); const page = await browser.newPage(); await page.goto("https://csfloat.com/search?def_index=4727"); let arr = await page.evaluate(() => { let text = document.getElementsByClassName("price ng-star-inserted"); let array = []; for (let i = 0; i < text.length; i++) { array.push(text[i].innerText); } // 这里要return结果,不然外面的arr拿不到数据! return array; }); console.log("爬取到的价格数据:", arr); // 记得最后关闭浏览器(如果需要的话) // await browser.close(); })();
这样启动后,Puppeteer打开的浏览器就是你已经登录过Steam和CSFloat的状态,直接就能爬取数据了。
方案二:手动注入已登录的Cookie(备选方案)
如果你不想关掉本地Chrome,或者因为某些原因不能复用用户目录,可以手动导出已登录状态的Cookie,然后在Puppeteer里注入这些Cookie,模拟登录状态。
操作步骤:
- 在已登录CSFloat的浏览器里导出Cookie:
- 打开CSFloat网站,按F12打开开发者工具
- 切换到「Application」标签,在左侧找到「Cookies」→ 选中CSFloat的域名
- 把所有Cookie条目导出成JSON格式(可以用控制台代码批量导出,或者用插件)
- 在Puppeteer里注入Cookie:
const puppeteer = require("puppeteer"); // 这里替换成你导出的Cookie数组 const csfloatCookies = [ { name: "cookie1", value: "xxx", domain: ".csfloat.com", path: "/", ... }, { name: "cookie2", value: "yyy", domain: ".csfloat.com", path: "/", ... }, // 所有Cookie条目都要加进来 ]; (async () => { const browser = await puppeteer.launch({headless: false}); const page = await browser.newPage(); // 先跳转到CSFloat的某个页面(必须和Cookie的域名匹配) await page.goto("https://csfloat.com"); // 注入Cookie await page.setCookie(...csfloatCookies); // 刷新页面,此时已经是登录状态了 await page.goto("https://csfloat.com/search?def_index=4727"); let arr = await page.evaluate(() => { let text = document.getElementsByClassName("price ng-star-inserted"); let array = []; for (let i = 0; i < text.length; i++) { array.push(text[i].innerText); } return array; }); console.log("爬取到的价格数据:", arr); })();
不过这个方法有个小缺点:Cookie会过期,过一段时间你就得重新导出一次,不如复用用户目录省心。
额外提示:修复你代码里的小问题
你原来的代码里,page.evaluate函数最后没有return array,所以外面的arr变量会是undefined——就算登录问题解决了,你也拿不到爬取的数据,一定要加上return语句哦!
关于其他库的问题
如果你不想用Puppeteer,Playwright是个不错的替代选择,它和Puppeteer功能类似,同样支持复用本地浏览器的用户目录,操作逻辑差不多,核心思路还是复用已有的登录会话,就不多赘述了。
备注:内容来源于stack exchange,提问作者Matvey Androsyuk




