israeli-bank-scrapers

repository·master·Indexed 21 days ago

https://github.com/eshaham/israeli-bank-scrapers

A collection of web scrapers for extracting financial data, including accounts and transactions, from major Israeli banks and credit card companies. The library supports various institutions such as Bank Leumi, Bank Hapoalim, Mizrahi, and Isracard, providing tools for handling 2FA, external Puppeteer browser instances, and specific credential requirements for each provider. It includes a core package, israeli-bank-scrapers-core, for environments like Electron where Chromium must be managed manually.

Tokens
10.2K
Snippets
37
Records
46
Agent score
76%

What's inside israeli-bank-scrapers

  1. Install and configure israeli-bank-scrapers-core

    master

    The israeli-bank-scrapers-core package is designed for environments like Electron where you want to manage Chromium manually using puppeteer-core.

    Steps to use core:

    1. Install the core package: npm install israeli-bank-scrapers-core --save.
    2. Determine the required Chromium revision using getPuppeteerConfig().chromiumRevision.
    3. Provide the absolute path to your local Chromium instance using the executablePath option in createScraper.
    import { getPuppeteerConfig, createScraper } from 'israeli-bank-scrapers-core';
    
    // 1. Get required revision
    const chromiumVersion = getPuppeteerConfig().chromiumRevision;
    
    // 2. Use in scraper (assuming you have downloaded chromium at this path)
    const options = {
      companyId: CompanyTypes.leumi,
      executablePath: '/path/to/your/chromium',
      // ... other options
    };
    const scraper = createScraper(options);
  2. Handle Two-Factor Authentication (2FA)

    master

    For companies requiring 2FA, you have two primary methods:

    1. Async Callback: Provide an otpCodeRetriever function in the login method that resolves with the OTP code (e.g., by prompting a user).
    2. Long Term Tokens: For supported scrapers (like OneZero), you can trigger 2FA, retrieve the code, and then use getLongTermTwoFactorToken(otpCode) to obtain a persistent token for future sessions.
    // Option 1: Async Callback
    const result = await scraper.login({
     email: 'user@example.com',
     password: 'password',
     phoneNumber: '0501234567',
     otpCodeRetriever: async () => {
      // Logic to get OTP (e.g. from user input or SMS service)
      return '123456';
     }
    });
    
    // Option 2: Long term token (OneZero example)
    await scraper.triggerTwoFactorAuth(phoneNumber);
    const otpCode = '...'; // retrieved via other means
    const tokenResult = scraper.getLongTermTwoFactorToken(otpCode);
    /*
     tokenResult = {
      success: true,
      longTermTwoFactorAuthToken: '...'
     }
     */
  3. Use an external browser context

    master

    To avoid sharing cookies between parallel scraper runs (e.g., different users), provide a Puppeteer browserContext in the options instead of a full browser instance.

    import puppeteer from 'puppeteer';
    import { CompanyTypes, createScraper } from 'israeli-bank-scrapers';
    
    const browser = await puppeteer.launch();
    const browserContext = await browser.createBrowserContext();
    const options = {
      companyId: CompanyTypes.leumi,
      startDate: new Date('2020-05-01'),
      browserContext
    };
    const scraper = createScraper(options);
    const scrapeResult = await scraper.scrape({ username: 'vr29485', password: 'sometingsomething' });
    await browser.close();
  4. Use an external browser instance

    master

    To control the browser lifecycle yourself (e.g., using an existing Puppeteer instance), pass a browser object in the options. Use skipCloseBrowser: true to prevent the library from automatically closing the browser when finished.

    import puppeteer from 'puppeteer';
    import { CompanyTypes, createScraper } from 'israeli-bank-scrapers';
    
    const browser = await puppeteer.launch();
    const options = {
      companyId: CompanyTypes.leumi,
      startDate: new Date('2020-05-01'),
      browser,
      skipCloseBrowser: true,
    };
    const scraper = createScraper(options);
    const scrapeResult = await scraper.scrape({ username: 'vr29485', password: 'sometingsomething' });
    await browser.close();
  5. Define login result matching logic

    master

    The possibleResults property in LoginOptions allows you to map the resulting URL (or other state) to a LoginResults type. This is critical for the scraper to know if it should proceed or report an error like InvalidPassword or ChangePassword.

    Supported condition types for matching:

    1. String: Case-insensitive exact match against the URL.
    2. RegExp: A regular expression tested against the URL.
    3. Function: An async function (options: { page: Page, value: string }) => Promise<boolean> that allows for complex logic using the Puppeteer Page instance.
    possibleResults: {
      'SUCCESS': ['https://bank.com/home'],
      'InvalidPassword': [/login\?error=wrong_pass/],
      'ChangePassword': async ({ page }) => {
        const url = page.url();
        return url.includes('reset-password');
      }
    }
  6. Identify Max transaction types

    master

    The Max scraper maps various internal plan names to standard TransactionTypes. Common mappings include:

    • Normal: Includes Normal, ImmediateCharge, MonthlyCharge, InternetShopping, MonthlyCardFee, etc.
    • Installments: Includes Installments, Credit, and CreditOutsideTheLimit.

    If a transaction type cannot be mapped via the plan name, the scraper falls back to checking the planTypeId (where IDs 2 and 3 are treated as Installments).

  7. Authenticate with One-Zero using Two-Factor Authentication

    master

    The OneZeroScraper requires a multi-step authentication process to handle Two-Factor Authentication (2FA). You can either provide a pre-existing otpLongTermToken or implement an otpCodeRetriever callback to handle the SMS code.

    To use the callback method:

    1. Provide a phoneNumber in international format (e.g., +972...).
    2. Provide an otpCodeRetriever function that returns the SMS code as a Promise<string>.

    If you are performing the steps manually, you can call triggerTwoFactorAuth(phoneNumber) first, then getLongTermTwoFactorToken(otpCode) to obtain a long-term token.

    const credentials = {
      email: 'user@example.com',
      password: 'your-password',
      phoneNumber: '+972501234567',
      otpCodeRetriever: async () => {
        // Logic to retrieve the SMS code from your system/user
        return '123456';
      }
    };
    
    const scraper = new OneZeroScraper();
    const loginResult = await scraper.login(credentials);
  8. Manage browser lifecycle and initialization

    master

    The BaseScraperWithBrowser class manages a Puppeteer browser instance. You can control how the browser is launched via the scraper's options:

    • Existing Browser: Provide browser or browserContext in the options to reuse an existing instance.
    • Headless Mode: Controlled by showBrowser. If showBrowser is false, the browser runs in headless mode.
    • Customization: Use prepareBrowser to run logic on the browser instance upon launch, and preparePage to run logic on the specific page instance after it is created.
    • Cleanup: The scraper automatically handles closing the page and the browser via the terminate method. If terminate is called with success: false, you can configure storeFailureScreenShotPath in the options to save a screenshot of the failure state.
  9. Quickstart: Scrape bank transactions

    master

    To scrape data, import CompanyTypes and createScraper. You must provide an options object (specifying the companyId and startDate) and a credentials object (containing username and password). Call scraper.scrape(credentials) to execute the process.

    import { CompanyTypes, createScraper } from 'israeli-bank-scrapers';
    
    (async function() {
      try {
        const options = {
          companyId: CompanyTypes.leumi, 
          startDate: new Date('2020-05-01'),
          combineInstallments: false,
          showBrowser: true 
        };
    
        const credentials = {
          username: 'vr29485',
          password: 'sometingsomething'
        };
    
        const scraper = createScraper(options);
        const scrapeResult = await scraper.scrape(credentials);
    
        if (scrapeResult.success) {
          scrapeResult.accounts.forEach((account) => {
            console.log(`found ${account.txns.length} transactions for account number ${account.accountNumber}`);
          });
        }
        else {
          throw new Error(scrapeResult.errorType);
        }
      } catch(e) {
        console.error(`scraping failed for the following reason: ${e.message}`);
      }
    })();
  10. Configure MaxScraper options

    master

    When initializing a MaxScraper, you can pass several options to control the data extraction behavior:

    • startDate (Date): The starting point for transaction scraping. Defaults to 1 year ago.
    • combineInstallments (boolean): If true, installments are grouped/fixed. If false, they are treated as individual transactions.
    • includeRawTransaction (boolean): If true, the resulting Transaction object will include the rawTransaction field containing the original unmapped data.
    • futureMonthsToScrape (number): How many months into the future to attempt scraping (defaults to 1).
    • outputData.enableTransactionsFilterByDate (boolean): Controls whether transactions older than the startDate are filtered out (defaults to true).
  11. Configure ScraperOptions for scraping tasks

    master

    When calling a scraper's scrape method, you provide a ScraperOptions object. This object controls the target bank, authentication context, browser behavior, and data processing.

    Core Options

    • companyId: The CompanyTypes identifier for the bank.
    • startDate: A Date object representing the start of the transaction period.
    • verbose: Boolean to include more debug info in output.
    • combineInstallments: If true, all installment transactions are combined into the first one.
    • additionalTransactionInformation: If true, performs extra operations (like categorization) per transaction (increases execution time).
    • includeRawTransaction: If true, includes the raw transaction object from the source (default: false).

    Browser & Execution Options

    Scraper options can be configured using one of three browser modes:

    1. DefaultBrowserOptions: Uses a managed Puppeteer instance. Includes showBrowser, executablePath, args, timeout (default 30000ms), and prepareBrowser hook.
    2. ExternalBrowserOptions: Provide an existing browser instance. Use skipCloseBrowser: true to prevent the library from closing your instance.
    3. ExternalBrowserContextOptions: Provide an existing browserContext.

    Data & Debugging

    • outputData: An OutputDataOptions object. Setting enableTransactionsFilterByDate: true prevents the scraper from filtering results by the startDate.
    • viewportSize: { width: number; height: number } (defaults to 1024x768).
    • navigationRetryCount: Number of retries for navigation failures (default 0).
    • storeFailureScreenShotPath: Path to save a screenshot if scraping fails.