产品更新 | 新的Profile功能

Advanced Data Extraction Specialist
为了增强 Scraping Browser 在跨会话场景中的实用性和稳定性,我们正式推出了用于持久用户数据的Profile功能。此功能将浏览器数据(例如 Cookie、存储、缓存和登录状态)存储在云中,使不同会话之间的无缝共享和重用成为可能 - 无需反复登录。它显著简化了调试过程,并提高了自动化脚本的效率。
为什么引入Profile功能?
在真实的自动化捕获或交互过程中,用户经常需要“记住登录状态”、“重用特定爬虫的 Cookie”和“在任务之间同步页面缓存”。传统的无头浏览器每次启动时都处于一个全新的环境中,无法保留任何历史上下文。
新的Profile功能通过使 Scraping Browser 支持以下内容解决了这个问题:
- 长期保留登录状态,消除每次重新认证的需要
- 在对同一网站的多个请求中保持一致的用户身份
- 在脚本调试时跨会话重用浏览器上下文
这个更新的亮点
Profile创建和管理页面现已上线
您现在可以前往“For Scraping → Profiles”进行:
- 创建/编辑/复制/删除
- 查看文件数据大小、最后使用时间
- 根据名称或 ID 搜索目标Profile
- 一键复制 ID 以供脚本或团队参考。
Profile详细页面:完全可视化的配置和使用历史
访问任何Profile以查看其完整配置和使用记录,包括:
- 基本信息: Profile名称、ID、数据大小、最后使用时间和总使用次数(即在会话中使用的次数)。
- 关联会话记录:
-
实时会话列表: 当前使用该Profile的实时会话;
-
会话历史列表: 所有使用该Profile的历史会话,条目可点击以获取详细查看。
-
这使调试过程更加透明,有助于更有效地重现和追踪问题。
与会话系统的深度集成
我们还在以下接口中添加了Profile信息显示和快速导航:
- 实时会话: 显示正在使用的Profile(可点击跳转至Profile详细页面)
- 会话历史: 显示与每个会话关联的Profile
- 会话详细信息: 允许您查看在特定运行时使用了哪个Profile
功能演示
案例 1:持久登录 + 提升加载速度
目标: 自动打开需要登录的页面,无需每次都输入您的用户名和密码。
步骤:
1. 第一次配置并保存登录状态。
创建个人资料的方式:
- 通过仪表板手动创建:通过仪表板手动创建Profile。
- API 创建:使用 创建个人资料 API 自动创建Profile。
- SDK 创建:使用 SDK 方法创建Profile。
NodeJS
javascript
import { Scrapeless } from "@scrapeless-ai/sdk"
const scrapeless = new Scrapeless({
apiKey: "YOUR_API_KEY"
})
// 创建一个新的Profile
const profile = await scrapeless.profiles.create("scrapeless_profile")
console.log("profile Id:", profile.profileId)
开始一个会话,然后指定 profile_id 并启用持久化,然后手动登录一次。登录状态(例如 Cookie 和令牌)将自动保存到云Profile中。
NodeJS
javascript
import puppeteer from "puppeteer-core"
import { Scrapeless } from "@scrapeless-ai/sdk"
const scrapeless = new Scrapeless({
apiKey: "YOUR_API_KEY"
});
async function main() {
const proxy= "YOUR_PROXY"
const profileId = "YOUR_PROFILE_ID" // 替换为您的 profileId
const { browserWSEndpoint } = scrapeless.browser.create({
proxy_country: "ANY",
proxy_url: proxy,
session_ttl: "900",
session_name: "Test Profile",
profile_id: profileId,
profile_persist: true,
});
const browser = await puppeteer.connect({
browserWSEndpoint,
defaultViewport: null,
})
const page = await browser.newPage()
await page.goto("https://the-internet.herokuapp.com/login", {
timeout: 30000,
waitUntil: "domcontentloaded",
})
const username = "your username"
const password = "your password!"
await page.type('[name="username"]', username)
await page.type('[name="password"]', password)
await Promise.all([
page.click('button[type="submit"]'),
page.waitForNavigation({ timeout: 15000 }).catch(() => { }),
])
const successMessage = await page.$(".flash.success")
if (successMessage) {
console.log("✅ 登录成功!")
} else {
console.log("❌ 登录失败。")
}
await browser.close()
}
main().catch(console.error)
2. 自动重用登录信息
- 在后续脚本或任务中重用相同的 profileId
- 启动一个新会话,引用之前创建的 profileId,自动登录到 https://the-internet.herokuapp.com/ 并打开个人主页
案例 2:自动绕过反机器人措施以提高自动化脚本成功率
目标: 在涉及反机器人措施和 CAPTCHA 的登录过程中,通过 profile 持久性绕过 CAPTCHA,以减少中断。
测试网站: https://www.leetchi.com/fr/login
步骤:
1. 通过 CAPTCHA 并保存状态
- 创建一个启用浏览器持久性的新的 Profile
- 手动登录并完成人工 CAPTCHA(例如,点击 CAPTCHA、选择图像等)
- 所有 CAPTCHA 结果和登录状态将保存到此 Profile中
2. 重用验证结果以实现自动登录
- 在脚本中使用相同的 profile_id 启动一个新会话
- 此会话将绕过 CAPTCHA 并自动登录,无需用户任何操作
案例 3:多会话 Cookie 共享
目标: 多个会话共享单一用户身份以进行并发操作,例如将商品添加到购物车。
用例: 管理多个浏览器,以并行访问像亚马逊这样的平台,并在同一帐户下执行不同的任务。
步骤:
1. 统一身份设置
- 在控制台中创建共享的Profile
- 输入用户名和密码登录亚马逊,成功登录后保存会话数据
NodeJS
import { Scrapeless } from "@scrapeless-ai/sdk"
import puppeteer from "puppeteer-core"
async function loginToAmazonWithSessionProfile() {
const token = "YOUR_API_KEY"; // API密钥
const proxy = "YOUR_PROXY"
const amazonAccountEmail = "YOUR_EMAIL"
const amazonAccountPassword = "YOUR_PASSWORD"
const profileName = "amazon";
const scrapeless = new Scrapeless({ apiKey: token });
let profile;
let profileId = "";
// 尝试获取现有Profile或创建新Profile
const profiles = await scrapeless.profiles.list({
name: profileName,
page: 1,
pageSize: 1,
});
if (profiles?.docs && profiles.docs.length > 0) {
profile = profiles.docs[0];
} else {
profile = await scrapeless.profiles.create(profileName);
}
profileId = profile?.profileId;
if (!profileId) {
return;
}
console.log(profile)
// 为Scrapeless浏览器构建连接URL
const { browserWSEndpoint } = scrapeless.browser.create({
proxy_country: "ANY",
proxy_url: proxy,
session_recording: true,
session_ttl: 900,
session_name: "登录亚马逊",
profile_id: profileId, // 特定的profileId
profile_persist: true, // 将浏览器数据持久化到Profile
})
const browser = await puppeteer.connect({
browserWSEndpoint: browserWSEndpoint
})
const page = await browser.newPage();
await page.goto("https://amazon.com", { waitUntil: "networkidle2" });
// 如果存在,则单击“继续购物”
try {
await page.waitForSelector("button.a-button-text", { timeout: 5000 });
await page.evaluate(() => {
const buttons = Array.from(document.querySelectorAll("button.a-button-text"));
const btn = buttons.find(b => b.textContent.trim() === "继续购物");
if (btn) btn.click();
});
console.log("点击了'继续购物'按钮。");
} catch (e) {
console.log("'继续购物'按钮未找到,继续...");
}
// 点击“登录”按钮
await page.waitForSelector("#nav-link-accountList", { timeout: 5000 });
await page.click("#nav-link-accountList");
console.log("点击了'登录'按钮。");
// 输入电子邮件
await page.waitForSelector("#ap_email_login", { timeout: 5000 });
await page.type("#ap_email_login", amazonAccountEmail, { delay: Math.floor(Math.random() * 91) + 10 });
console.log("输入了电子邮件。");
// 点击“继续”
await page.waitForSelector("#continue-announce", { timeout: 5000 });
await page.click("#continue-announce");
console.log("点击了'继续'按钮。");
// 输入密码,每个字符随机延迟
await page.waitForSelector("#ap_password", { timeout: 5000 });
for (const char of amazonAccountPassword) {
await page.type("#ap_password", char, { delay: Math.floor(Math.random() * 91) + 10 });
}
console.log("输入了密码。");
// 点击“登录”提交按钮
await page.waitForSelector("#signInSubmit", { timeout: 5000 });
await page.click("#signInSubmit");
console.log("点击了'登录'提交按钮。");
可选: await page.waitForNavigation();
await browser.close();
}
(async () => {
await loginToAmazonWithSessionProfile();
})();
2. 使用一致身份的并发调用
-
启动多个会话(例如,3个),所有会话都引用相同的
profile_id
-
所有会话在同一用户身份下运行
-
分别执行不同的页面操作,例如将产品A、B和C添加到购物车
-
会话1搜索
鞋子
并将其添加到购物车
import { Scrapeless } from "@scrapeless-ai/sdk"
import puppeteer from "puppeteer-core"
async function addGoodsToCart() {
const token = "YOUR_API_KEY"
const proxy = "YOUR_PROXY"
const profileId = "YOUR_PROFILE_ID"
const search = "鞋子"
const scrapeless = new Scrapeless({
apiKey: token
})
// 创建浏览器会话
const { browserWSEndpoint } = scrapeless.browser.create({
proxy_country: "ANY",
proxy_url: proxy,
session_recording: true,
session_ttl: 900,
session_name: `商品 ${search}`,
profile_id: profileId,
profile_persist: false, // 禁用会话持久化
})
const client = await puppeteer.connect({
browserWSEndpoint: browserWSEndpoint
})
const page = await client.newPage()
try {
await page.goto("https://www.amazon.com", { waitUntil: "networkidle2" })
```zh
await page.waitForSelector('input[id="twotabsearchtextbox"]', { timeout: 5000 })
// 搜索商品
console.log(`搜索商品: ${search}`);
await page.type('input[id="twotabsearchtextbox"]', search, { delay: Math.floor(Math.random() * 91) + 10 });
await page.keyboard.press('Enter');
await page.waitForSelector('button[id="a-autoid-3-announce"]', { timeout: 10000 })
// 点击商品
await page.click('button[id="a-autoid-3-announce"]')
console.log(`点击商品`);
await page.waitForSelector('div[id="a-popover-content-2"]', { timeout: 10000 })
await new Promise((resolve) => setTimeout(resolve, 5000))
const buttons = await page.$$('div#a-popover-content-2 button.a-button-text');
if (buttons.length > 0) {
// 点击加入购物车
await buttons[0].click();
console.log(`点击加入购物车`);
}
await client.close();
} catch (e) {
console.log("添加购物车失败。", e);
}
}
(async () => {
await addGoodsToCart()
})()
- 会话2搜索
clothes
并将其加入购物车
import { Scrapeless } from "@scrapeless-ai/sdk"
import puppeteer from "puppeteer-core"
async function addGoodsToCart() {
const token = "YOUR_API_KEY"
const proxy = "YOUR_PROXY"
const profileId = "YOUR_PROFILE_ID"
const search = "clothes"
const scrapeless = new Scrapeless({
apiKey: token
})
// 创建浏览器会话
const { browserWSEndpoint } = scrapeless.browser.create({
proxy_country: "ANY",
proxy_url: proxy,
session_recording: true,
session_ttl: 900,
session_name: `商品 ${search}`,
profile_id: profileId,
profile_persist: false, // 禁用会话持久化
})
const client = await puppeteer.connect({
browserWSEndpoint: browserWSEndpoint
})
const page = await client.newPage()
try {
await page.goto("https://www.amazon.com", { waitUntil: "networkidle2" })
await page.waitForSelector('input[id="twotabsearchtextbox"]', { timeout: 5000 })
// 搜索商品
console.log(`搜索商品: ${search}`);
await page.type('input[id="twotabsearchtextbox"]', search, { delay: Math.floor(Math.random() * 91) + 10 });
await page.keyboard.press('Enter');
await page.waitForSelector('button[id="a-autoid-3-announce"]', { timeout: 10000 })
// 点击商品
await page.click('button[id="a-autoid-3-announce"]')
console.log(`点击商品`);
await page.waitForSelector('div[id="a-popover-content-2"]', { timeout: 10000 })
await new Promise((resolve) => setTimeout(resolve, 5000))
const buttons = await page.$$('div#a-popover-content-2 button.a-button-text');
if (buttons.length > 0) {
// 点击加入购物车
await buttons[0].click();
console.log(`点击加入购物车`);
}
await client.close();
} catch (e) {
console.log("添加购物车失败。", e);
}
}
(async () => {
await addGoodsToCart()
})()
- 会话3搜索
pants
并将其加入购物车
import { Scrapeless } from "@scrapeless-ai/sdk"
import puppeteer from "puppeteer-core"
async function addGoodsToCart() {
const token = "YOUR_API_KEY"
const proxy = "YOUR_PROXY"
const profileId = "YOUR_PROFILE_ID"
const search = "pants"
const scrapeless = new Scrapeless({
apiKey: token
})
// 创建浏览器会话
const { browserWSEndpoint } = scrapeless.browser.create({
proxy_country: "ANY",
proxy_url: proxy,
session_recording: true,
session_ttl: 900,
session_name: `商品 ${search}`,
profile_id: profileId,
profile_persist: false, // 禁用会话持久化
})
const client = await puppeteer.connect({
browserWSEndpoint: browserWSEndpoint
})
const page = await client.newPage()
try {
await page.goto("https://www.amazon.com", { waitUntil: "networkidle2" })
await page.waitForSelector('input[id="twotabsearchtextbox"]', { timeout: 5000 })
// 搜索商品
console.log(`搜索商品: ${search}`);
await page.type('input[id="twotabsearchtextbox"]', search, { delay: Math.floor(Math.random() * 91) + 10 });
await page.keyboard.press('Enter');
await page.waitForSelector('button[id="a-autoid-3-announce"]', { timeout: 10000 })
// 点击商品
await page.click('button[id="a-autoid-3-announce"]')
console.log(`点击商品`);
await page.waitForSelector('div[id="a-popover-content-2"]', { timeout: 10000 })
await new Promise((resolve) => setTimeout(resolve, 5000))
const buttons = await page.$$('div#a-popover-content-2 button.a-button-text');
if (buttons.length > 0) {
// 点击加入购物车
javascript
await buttons[0].click();
console.log(`点击了添加到购物车`);
}
await client.close();
} catch (e) {
console.log("添加购物车失败。", e);
}
}
(async () => {
await addGoodsToCart()
})()

这些功能适合哪些场景?
Profiles 的推出显著提升了 Scraping Browser 在多用户、多会话和复杂工作流程环境中的性能。以下是一些典型的实际用例:
自动化数据收集 / 爬虫项目
在频繁爬取需要登录的网站(如电子商务、招聘或社交媒体平台)时:
- 持久化登录状态以避免频繁触发风险控制;
- 保留关键上下文,如 Cookies、存储和令牌;
- 为不同任务分配不同身份(Profiles)以管理账户池或身份池。
团队协作 / 多环境配置管理
在开发、测试和运维团队中:
- 每个成员维护自己的 Profile 配置而不受干扰;
- Profile ID 可以直接嵌入自动化脚本中以确保一致的调用;
- 支持自定义命名和批量清理,以保持环境整洁有序。
质量保证 / 客户支持 / 在线问题重现
- QA 可以预设与关键测试用例关联的 Profiles,避免在回放时重建状态;
- 客户支持场景可以通过 Profiles 恢复客户的操作环境,以准确重现问题;
- 所有会话可以链接到 Profile 使用记录,便于排查与上下文相关的问题。
👉 打开 Playground 并立即体验。
在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。