Skip to content

Dyotson/RacionalScrapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Racional Scrapper

A Python library and CLI tool that scrapes portfolio holdings from Racional, a Chilean investment platform. Since Racional has no public API, this tool uses headless browser automation (Playwright) to log in, handle email-based 2FA, and intercept the internal API responses to extract your positions.

What it extracts

For each position in your Racional Stocks account:

Field Description
symbol Ticker symbol (e.g. VRT, CEG)
shares Number of shares (supports fractional)
avg_cost Average cost basis per share (USD)
market_value_usd Current market value (USD)
unrealized_pl Unrealized profit/loss (USD)
unrealized_pl_pct Unrealized P/L as percentage
weight_pct Position weight in portfolio (%)

It also extracts cash (buying power available for trading).

How it works

1. Launch headless Chromium via Playwright
2. Navigate to app.racional.cl/login
3. Fill email + password, submit
4. Detect 2FA modal -> read OTP code from Gmail via IMAP
5. Submit 2FA code
6. Navigate to portfolio page
7. Intercept api.racional.cl/positions JSON response
8. Return structured holdings data

The tool intercepts Racional's internal api.racional.cl/positions endpoint (which powers the frontend) rather than scraping DOM elements, making it more reliable.

Prerequisites

  • Python 3.10+
  • A Racional account
  • A Gmail account (for reading 2FA codes via IMAP)
  • A Gmail App Password (requires 2-Step Verification on your Google account)

Installation

# Clone the repository
git clone https://github.com/maximilianomilitzer/RacionalScrapper.git
cd RacionalScrapper

# Install the package
pip install .

# Install Playwright's Chromium browser
playwright install chromium

Or install in development mode:

pip install -e .
playwright install chromium

Configuration

Copy the example environment file and fill in your credentials:

cp .env.example .env

Edit .env:

RACIONAL_EMAIL=your-email@gmail.com
RACIONAL_PASSWORD=your-racional-password

# Gmail App Password for reading 2FA emails
IMAP_USER=your-email@gmail.com
IMAP_PASSWORD=abcd-efgh-ijkl-mnop

Getting a Gmail App Password

  1. Go to myaccount.google.com/apppasswords
  2. You need 2-Step Verification enabled on your Google account
  3. Create a new App Password (select "Mail" or "Other")
  4. Copy the 16-character password into IMAP_PASSWORD

Usage

CLI

# Scrape holdings (table output)
racional-scrapper

# Scrape holdings (JSON output)
racional-scrapper --json

# Discovery mode: dump all intercepted API responses
racional-scrapper --discover

# Run with visible browser for debugging
racional-scrapper --no-headless

# Verbose logging
racional-scrapper -v

Example output:

Scraped 4 holdings (cash: $0)

Symbol      Shares     Avg Cost    Value (USD)      P/L %
------------------------------------------------------------
AEM         1.5804       250.97         367.81      -7.27%
CEG         1.5614       322.85         504.10       9.62%
SGOV        8.5000       100.02         850.20       0.01%
VRT        15.2000        92.65        1408.58      49.35%

Python API

from racional_scrapper import scrape_holdings

result = scrape_holdings(
    email="your-email@gmail.com",
    password="your-racional-password",
    imap_user="your-email@gmail.com",
    imap_password="your-gmail-app-password",
)

for holding in result["holdings"]:
    print(f"{holding['symbol']}: {holding['shares']} shares @ ${holding['avg_cost']:.2f}")

print(f"Cash available: ${result['cash']}")

The scrape_holdings() function returns:

{
    "holdings": [
        {
            "symbol": "VRT",
            "shares": 15.2,
            "avg_cost": 92.65,
            "market_value_usd": 1408.58,
            "unrealized_pl": 468.72,
            "unrealized_pl_pct": 49.85,
            "weight_pct": 45.0,
        },
        # ...
    ],
    "cash": Decimal("0"),
    "account_summary": { ... },  # Raw DriveWealth account summary JSON
}

Discovery mode

If the scraper breaks (e.g. Racional updates their app), use discovery mode to inspect what API calls the app is making:

from racional_scrapper import discover

result = discover(
    email="your-email@gmail.com",
    password="your-racional-password",
    imap_user="your-email@gmail.com",
    imap_password="your-gmail-app-password",
)

for url in result["urls"]:
    print(url)

Docker

If you want to run this in a container:

FROM python:3.12-slim

WORKDIR /app

COPY . .
RUN pip install --no-cache-dir . && \
    playwright install chromium && \
    playwright install-deps

CMD ["racional-scrapper", "--json"]

Notes

  • Racional uses email-based 2FA on every login. The scraper handles this automatically by reading the OTP code from Gmail via IMAP.
  • The 2FA code expires after 5 minutes. The IMAP poller waits up to 90 seconds for the email to arrive.
  • Racional is an Ionic/Angular SPA that uses Firebase for authentication and DriveWealth as the brokerage backend.
  • This tool only reads your portfolio data. It does not execute trades or modify your account in any way.

Disclaimer

This tool is not affiliated with, endorsed by, or associated with Racional SpA. Use it at your own risk and in compliance with Racional's terms of service. The author is not responsible for any consequences of using this tool.

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages