Fintech Developer Tools 127 vues

Stop Manually Exporting Bank Data! Israeli-Bank-Scrapers Does It All

B
Bright Coding
Auteur
Stop Manually Exporting Bank Data! Israeli-Bank-Scrapers Does It All

Stop Manually Exporting Bank Data! Israeli-Bank-Scrapers Does It All

What if I told you that every hour you spend manually downloading CSV files from your Israeli bank is an hour you'll never get back? That the copy-paste dance between Bank Hapoalim, Leumi, Discount, and your spreadsheet is a problem that top developers solved years ago?

Here's the painful truth: Israeli banks are notorious for their clunky interfaces, inconsistent export formats, and zero API access. Want to build a personal finance dashboard? Good luck wrestling with 17 different login systems. Need automated transaction tracking for your startup's bookkeeping? Prepare for a nightmare of manual downloads.

But what if there was a single library that could talk to Bank Hapoalim, Leumi, Discount, Mizrahi, Visa Cal, Max, Isracard, and 10 more financial institutions—all through clean, modern JavaScript↗ Bright Coding Blog?

Enter israeli-bank-scrapers. This isn't just another scraping tool. It's the secret weapon that Israeli developers, fintech founders, and automation engineers have been quietly using to reclaim their time. Built on battle-tested Puppeteer automation, this open-source powerhouse transforms hours of manual drudgery into a single npm install and a few lines of code.

Ready to see how the pros handle financial data? Let's dive in.


What is Israeli-Bank-Scrapers?

israeli-bank-scrapers is a comprehensive Node.js library that provides automated scrapers for all major Israeli banks and credit card companies. Created by Elad Shaham and maintained by a thriving open-source community, it has become the de facto standard for programmatic financial data extraction in Israel's ecosystem.

The project addresses a critical gap in Israeli fintech: while banks worldwide have embraced open banking APIs, Israeli financial institutions remain locked behind legacy web interfaces with zero official programmatic access. This library bridges that gap through intelligent browser automation using Puppeteer, Google's official Node.js library for controlling headless Chrome.

What makes this project genuinely remarkable is its community-driven expansion. What started as a single scraper has grown to 17 supported institutions, with contributions from developers across Israel's tech landscape—including dedicated teams from Intuit's FDP OpenSource Team who built scrapers for Union Bank and Beinleumi. The project maintains active Discord community support and publishes automatically to NPM on every master branch merge.

The library is published in two flavors: the default israeli-bank-scrapers (bundling Puppeteer with Chromium) and israeli-bank-scrapers-core (using puppeteer-core for Electron apps and size-sensitive deployments). This dual-publication strategy demonstrates mature project governance—acknowledging that different use cases demand different trade-offs between convenience and bundle size.


Key Features That Make It Irresistible

Universal Institution Coverage

The library doesn't play favorites. From Bank Hapoalim to experimental OneZero support, from traditional banks to credit card companies like Visa Cal, Max, Isracard, and Amex—even niche providers like Beyhad Bishvilha and Behatsdaa are covered. This breadth eliminates the fragmentation nightmare of maintaining separate scraping solutions.

Intelligent Timezone Handling

Here's a subtle killer feature: scrapers automatically use Asia/Jerusalem timezone. Running your automation from a VPS in Frankfurt? Your AWS↗ Bright Coding Blog Lambda in Virginia? No problem. Date boundaries align correctly with Israeli banking days, preventing the off-by-one errors that plague naive scraping implementations.

Flexible Authentication Strategies

The library handles the full spectrum of Israeli banking security:

  • Standard username/password for most institutions
  • Multi-field credentials (ID + password + code for Discount/Mercantile)
  • Two-factor authentication with callback-based OTP retrieval
  • Long-term token persistence for providers like OneZero that support it

Production-Ready Browser Control

Advanced users can inject externally created browser instances or browser contexts, enabling:

  • Parallel multi-account scraping without cookie collision
  • Custom Chromium paths for containerized deployments
  • Memory-efficient context isolation versus full browser instances

Structured, Predictable Output

Every scraper returns identical data structures regardless of source institution. Transactions include normalized fields: type (normal/installments), identifier, date, processedDate, originalAmount, originalCurrency, chargedAmount, description, memo, installment metadata, and status (completed/pending). No more parsing inconsistent CSV formats.

Opt-In Breaking Changes

The optInFeatures system allows the maintainers to ship improvements without breaking existing integrations. New behavior is gated behind explicit flags—enterprise-grade stability thinking in an open-source project.


Real-World Use Cases Where It Shines

1. Personal Finance Automation

Tools like Caspion and Moneyman use israeli-bank-scrapers to automatically sync transactions to YNAB, Actual Budget, and Firefly III. Set it up once, run it on GitHub Actions, and your budget stays current without touching a bank website.

2. Startup Bookkeeping Pipelines

Israeli startups juggling corporate cards from multiple providers can build unified expense tracking. Imagine scraping Amex, Isracard, and Max daily, feeding everything into your accounting system via a single API. No more month-end spreadsheet marathons.

3. Financial Alert Systems

The Finance Notifier demonstrates custom alerting: monitor specific merchants, flag unusual amounts, or track spending against budgets. The scraper becomes your financial watchdog.

4. LLM-Powered Financial Analysis

Asher MCP pushes into cutting-edge territory: scraping data and exposing it to large language models via the Model Context Protocol. Ask natural language questions about your spending patterns across all institutions.

5. Multi-Account Aggregation Services

Fintech builders can construct Israeli equivalents of Mint or Plaid—consolidated dashboards showing complete financial pictures. The library's consistent output format makes this architecturally clean.

6. Regulatory Compliance & Audit Trails

Businesses needing transaction history for tax audits can automate retention. Most scrapers fetch 6-12 months of data—programmatically archive everything before records expire from bank websites.


Step-by-Step Installation & Setup Guide

Prerequisites

You'll need Node.js >= 22.12.0. Verify your version:

node --version
# Must output v22.12.0 or higher

Standard Installation

For most server applications, CLIs, and scripts:

npm install israeli-bank-scrapers --save

This installs Puppeteer with bundled Chromium (~300MB). The library handles Chromium management automatically.

Core Variation (Electron, Size-Sensitive Apps)

For applications where bundle size matters:

npm install israeli-bank-scrapers-core --save

You'll need to manage Chromium manually. First, query the required revision:

import { getPuppeteerConfig } from 'israeli-bank-scrapers-core';

const chromiumVersion = getPuppeteerConfig().chromiumRevision;
console.log(`Required Chromium revision: ${chromiumVersion}`);

Then download that specific revision (the download-chromium package helps here) and provide its absolute path:

const options = {
  companyId: CompanyTypes.leumi,
  executablePath: '/path/to/your/chromium', // Critical for core variation
  startDate: new Date('2020-05-01'),
};

Environment Setup Checklist

  1. Ensure stable network—bank scrapers are sensitive to timeouts
  2. Set TZ=Asia/Jerusalem if your server runs outside Israel (though the library handles this internally)
  3. For CI/CD: Use showBrowser: false (headless mode)
  4. For debugging: Use showBrowser: true to watch automation in action

REAL Code Examples from the Repository

Example 1: Basic Scraping with Error Handling

This is the canonical getting-started pattern from the README, enhanced with detailed commentary:

Advertisement
import { CompanyTypes, createScraper } from 'israeli-bank-scrapers';

(async function() {
  try {
    // Configure scraper behavior—see interface.ts for all options
    const options = {
      companyId: CompanyTypes.leumi,  // Target institution enum
      startDate: new Date('2020-05-01'), // How far back to fetch
      combineInstallments: false,      // Keep installment transactions separate
      showBrowser: true                // Set false for headless/production
    };

    // Credentials match Leumi's expected structure (username + password)
    const credentials = {
      username: 'vr29485',
      password: 'sometingsomething'
    };

    // Factory pattern: create configured scraper instance
    const scraper = createScraper(options);
    
    // The actual scraping operation—returns Promise<ScrapeResult>
    const scrapeResult = await scraper.scrape(credentials);

    if (scrapeResult.success) {
      // Iterate all discovered accounts (some users have multiple)
      scrapeResult.accounts.forEach((account) => {
        console.log(
          `found ${account.txns.length} transactions ` +
          `for account number ${account.accountNumber}`
        );
        // account.balance available for some institutions
        // account.txns contains full transaction array
      });
    } else {
      // Structured error types enable programmatic handling
      throw new Error(scrapeResult.errorType);
    }
  } catch(e) {
    // Catches both scraper errors and our thrown errorType
    console.error(`scraping failed: ${e.message}`);
  }
})();

Why this pattern works: The createScraper factory decouples configuration from execution. The scrapeResult discriminated union (success boolean) forces proper error handling. Note how CompanyTypes.leumi provides compile-time safety against typos in institution names.

Example 2: Understanding the Result Structure

The library returns deeply structured data regardless of source institution:

{
  success: true,           // Boolean gate for all downstream processing
  accounts: [{
    accountNumber: "123-456789/00", // Normalized string identifier
    balance: 15420.50,     // Optional: not all scrapers implement
    txns: [{
      type: "normal",      // "normal" | "installments"
      identifier: 9876543, // Bank's internal transaction ID
      date: "2024-01-15",  // ISO 8601 date string (transaction date)
      processedDate: "2024-01-17", // When it actually cleared
      originalAmount: -250.00,     // Negative for debits
      originalCurrency: "ILS",     // Source currency
      chargedAmount: -250.00,      // After conversion/fees
      description: "SUPER-PHARM 245", // Merchant/transaction description
      memo: "",              // Additional details (often empty)
      installments: null,    // Present only for installment transactions
      status: "completed"    // "completed" | "pending"
    }, {
      type: "installments",
      // ... other fields ...
      installments: {
        number: 3,           // This is payment 3 of...
        total: 12            // ...12 total installments
      }
    }]
  }],
  // Only present when success: false
  errorType: "INVALID_PASSWORD", // Enum for programmatic handling
  errorMessage: "Login failed: incorrect credentials"
}

Critical insight: The originalAmount versus chargedAmount distinction handles foreign currency transactions and fee scenarios. The processedDate versus date split captures the common Israeli pattern where transaction date differs from clearing date.

Example 3: Advanced Browser Context Isolation

For production multi-tenant systems, share one browser across parallel scrapes:

import puppeteer from 'puppeteer';
import { CompanyTypes, createScraper } from 'israeli-bank-scrapers';

// Launch single browser instance—expensive operation, do once
const browser = await puppeteer.launch();

// Create isolated contexts: separate cookies, localStorage, caches
const contextA = await browser.createBrowserContext();
const contextB = await browser.createBrowserContext();

// Scrape two different Leumi accounts simultaneously
const [resultA, resultB] = await Promise.all([
  createScraper({
    companyId: CompanyTypes.leumi,
    startDate: new Date('2024-01-01'),
    browserContext: contextA  // Isolated from contextB
  }).scrape({ username: 'user1', password: 'pass1' }),
  
  createScraper({
    companyId: CompanyTypes.leumi,
    startDate: new Date('2024-01-01'),
    browserContext: contextB  // No cookie leakage risk
  }).scrape({ username: 'user2', password: 'pass2' })
]);

await browser.close();

Performance win: Browser launch (~2-3 seconds) happens once. Context creation is near-instant. This pattern scales to dozens of parallel scrapes without proportional resource growth.

Example 4: Two-Factor Authentication Handling

For institutions requiring OTP, provide async callbacks:

import { CompanyTypes, createScraper } from 'israeli-bank-scrapers';
import { prompt } from 'enquirer';

const scraper = createScraper({ companyId: CompanyTypes.oneZero });

const result = await scraper.login({
  email: 'user@example.com',
  password: 'secret',
  phoneNumber: '+972501234567',
  
  // Async callback invoked when OTP needed
  otpCodeRetriever: async () => {
    let otpCode;
    while (!otpCode) {
      // Interactive prompt—replace with SMS API in production
      const response = await prompt({
        type: 'input',
        name: 'otp',
        message: 'Enter OTP Code:'
      });
      otpCode = response.otp;
    }
    return otpCode;
  }
});

For OneZero specifically, retrieve long-term tokens to avoid repeated 2FA:

// Trigger OTP once
await scraper.triggerTwoFactorAuth('+972501234567');

// User receives code, you capture it
const otpCode = '123456'; // From SMS, push notification, etc.

// Exchange for persistent token
const result = scraper.getLongTermTwoFactorToken(otpCode);
/*
result = {
  success: true,
  longTermTwoFactorAuthToken: 'eyJraWQiOiJiNzU3OGM5Yy0wM2YyLTRkMzktYjBm...'
  // Store this token securely—reuse for months
}
*/

Advanced Usage & Best Practices

Credential Security

Never hardcode credentials as shown in examples. Use environment variables or secret managers:

const credentials = {
  username: process.env.LEUMI_USERNAME,
  password: process.env.LEUMI_PASSWORD
};

Rate Limiting & Politeness

Israeli banks implement aggressive bot detection. Space requests reasonably, avoid parallel logins to the same institution from the same IP, and consider proxy rotation for high-frequency operations.

Transaction Deduplication

The identifier field enables idempotent processing. Store seen identifiers in your database to prevent duplicate imports when re-scraping date ranges.

Date Range Optimization

Most scrapers support 6-12 months of history. For initial backfill, chunk requests monthly. For ongoing sync, use startDate: lastSuccessfulRunDate to minimize scrape time.

Headless Detection Evasion

Some banks detect headless Chrome. If encountering issues, experiment with Puppeteer's stealth plugins or use showBrowser: true with virtual display (Xvfb) in containers.

Monitoring & Alerting

Wrap scrapers in health checks. Track errorType distributions—spikes in TIMEOUT or GENERIC errors often indicate bank website changes requiring library updates.


Comparison with Alternatives

Aspect Israeli-Bank-Scrapers Manual CSV Export Screen Scraping DIY Official Bank APIs
Setup Time 5 minutes Zero (ongoing pain) Days to weeks Months (if available)
Institution Coverage 17+ providers All (manual each) One at a time Zero in Israel
Maintenance Burden Community handled Constant manual work Full personal burden N/A
Output Format Structured JSON Inconsistent CSVs Whatever you build N/A
Automation Ready Yes No Only if you build it N/A
2FA Handling Built-in callbacks N/A Must implement N/A
Timezone Correctness Automatic Manual adjustment Must implement N/A
Cost Free (MIT) Free (your time) Your development time N/A

The brutal truth: For Israeli financial data, there effectively are no official APIs. Your alternatives are perpetual manual work or building fragile scrapers that break when bank websites redesign. This library represents thousands of collective hours of community maintenance that you'd otherwise duplicate.


FAQ

What Node.js version is required?

Node.js >= 22.12.0 is mandatory. The library uses modern features and dependencies that require this baseline.

Is this legal to use with my own accounts?

The library accesses your own financial data using your credentials—similar to using a password manager or personal finance app. However, review your bank's terms of service and consider consulting legal counsel for commercial use cases.

Can I use this in production systems?

Absolutely. Projects like Moneyman run on GitHub Actions 24/7. Use appropriate error handling, monitoring, and credential security practices.

What happens when a bank changes their website?

The active community typically updates scrapers within days. Follow the repository for updates, and pin versions in production to control when changes deploy.

Does it support business/corporate accounts?

Support varies by institution. The scrapers target standard retail interfaces. Corporate banking portals with additional security layers may require adaptation.

How do I handle CAPTCHAs?

The library doesn't bypass CAPTCHAs. Some institutions rarely show them; others may require showBrowser: true with human intervention, or third-party solving services integrated into your workflow.

Can I scrape multiple accounts simultaneously?

Yes, using browser contexts (Example 3 above) or separate browser instances. Be mindful of rate limiting and IP-based detection.


Conclusion

The israeli-bank-scrapers library represents something rare in fintech: a genuinely solved problem. What begins as an afternoon of frustrated clicking through bank portals becomes a 20-line script that runs while you sleep.

I've seen too many developers burn weekends building fragile scrapers that collapse at the first website redesign. This library's 17 supported institutions, consistent data model, and active maintenance community make it the obvious choice for any Israeli financial automation.

The ecosystem around it—from YNAB exporters to LLM-powered analysis tools—proves its versatility. Whether you're automating personal budgets or building the next Israeli fintech unicorn, start here rather than reinventing the wheel.

Your next step: npm install israeli-bank-scrapers, pick your institution from the CompanyTypes enum, and watch your transaction data flow in structured JSON. The repository's README and Discord community await when you need deeper guidance.

Stop exporting CSVs. Start building.


Star the repository, contribute scrapers for missing institutions, or build something amazing and share it with the community.

Advertisement

Commentaires 0

Aucun commentaire pour l'instant. Soyez le premier à réagir !

Laisser un commentaire

Advertisement