Skip to content

Workflow 002: Authenticated Scraping Pipeline

Fresh

Overview

Build a scraping pipeline that authenticates once and reuses credentials across multiple sessions for accessing protected content.

Pipeline Architecture

Choose Your Auth Strategy

StrategyBest ForPersistenceSetup
Credentials APIAutomated login, multi-userPermanent until deletedStore once, inject always
Auth ContextQuick session transferPer-captureCapture each time
Browser ProfilesFull browser state30 daysPersist on release

Implementation: Credentials API Approach

typescript
// One-time: Store credentials
await client.credentials.create({
  origin: "https://app.example.com",
  namespace: "scraper:main",
  value: {
    username: "scraper@company.com",
    password: "secure_password",
    totpSecret: "JBSWY3DPEHPK3PXP"  // Optional
  }
});

// Every run: Auto-authenticated session
const session = await client.sessions.create({
  namespace: "scraper:main",
  credentials: { autoSubmit: true },
  useProxy: true,
});

const browser = await chromium.connectOverCDP(
  `wss://connect.steel.dev?apiKey=${process.env.STEEL_API_KEY}&sessionId=${session.id}`
);

const page = browser.contexts()[0].pages()[0];
await page.goto("https://app.example.com/login");
await page.waitForTimeout(3000);  // Wait for auto-login
await page.waitForSelector(".dashboard");  // Confirm auth

// Now scrape protected pages
const data = await scrapePages(page, urls);

await browser.close();
await client.sessions.release(session.id);

Implementation: Profile-Based Approach

typescript
// First run: Login and persist
const session1 = await client.sessions.create({ persistProfile: true });
// ... connect, login manually ...
await client.sessions.release(session1.id);

// Subsequent runs: Already authenticated
const session2 = await client.sessions.create({
  profileId: session1.profileId,
  useProxy: true,
});
// ... navigate directly to protected content ...

See Also

SOP Documentation Hub - Built from Steel.dev Official Docs