🥳加入无抓取社区领取您的免费试用,访问我们强大的网页抓取工具包!
返回博客

产品更新 | 新的Profile功能

Emily Chen
Emily Chen

Advanced Data Extraction Specialist

17-Jul-2025

为了增强 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 Copy
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 Copy
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 并自动登录,无需用户任何操作

目标: 多个会话共享单一用户身份以进行并发操作,例如将商品添加到购物车。
用例: 管理多个浏览器,以并行访问像亚马逊这样的平台,并在同一帐户下执行不同的任务。

步骤:

1. 统一身份设置

  • 在控制台中创建共享的Profile
  • 输入用户名和密码登录亚马逊,成功登录后保存会话数据

NodeJS

Copy
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搜索 鞋子 并将其添加到购物车

Copy
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 并将其加入购物车
Copy
 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 并将其加入购物车
Copy
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 Copy
await buttons[0].click();
console.log(`点击了添加到购物车`);
}
await client.close();
} catch (e) {
console.log("添加购物车失败。", e);
}
}

(async () => {
await addGoodsToCart()
})()
案例 3:多会话 Cookie 共享

这些功能适合哪些场景?

Profiles 的推出显著提升了 Scraping Browser 在多用户、多会话和复杂工作流程环境中的性能。以下是一些典型的实际用例:

自动化数据收集 / 爬虫项目

在频繁爬取需要登录的网站(如电子商务、招聘或社交媒体平台)时:

  • 持久化登录状态以避免频繁触发风险控制;
  • 保留关键上下文,如 Cookies、存储和令牌;
  • 为不同任务分配不同身份(Profiles)以管理账户池或身份池。

团队协作 / 多环境配置管理

在开发、测试和运维团队中:

  • 每个成员维护自己的 Profile 配置而不受干扰;
  • Profile ID 可以直接嵌入自动化脚本中以确保一致的调用;
  • 支持自定义命名和批量清理,以保持环境整洁有序。

质量保证 / 客户支持 / 在线问题重现

  • QA 可以预设与关键测试用例关联的 Profiles,避免在回放时重建状态;
  • 客户支持场景可以通过 Profiles 恢复客户的操作环境,以准确重现问题;
  • 所有会话可以链接到 Profile 使用记录,便于排查与上下文相关的问题。

👉 打开 Playground 并立即体验。

在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。

最受欢迎的文章

目录