nl2go / hetzner-invoice

Automatically download and transform Hetzner invoices.
MIT License
12 stars 1 forks source link

Hetzner security check #26

Open ScepticMatt opened 1 year ago

ScepticMatt commented 1 year ago

Hetzner has implemented a security check (wich simple forwarding) to try and prevent bot access:

image

smarakdas314 commented 7 months ago

you can use playwright to simulate web browser, very sad Hetzner doesn't give API, scripts means to download csv invoices here's my day of work you can use

pip install playwright playwright-stealth && playwright install chromium

Script downloads latest invoice to /tmp

from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync
import time

USERNAME = "admin@foobar.com"
PASSWORD = "CHANGEME"

def main():
    with sync_playwright() as p:
        # Launch a browser
        browser = p.chromium.launch(headless=True)

        # Create a new context with a custom user agent
        context = browser.new_context(user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36')

        # Create a new page within the context
        page = context.new_page()
        stealth_sync(page)

        # Navigate to a website
        page.goto('https://accounts.hetzner.com/login')

        # Fill in the username and password fields
        page.type('input#_username', USERNAME) 
        page.type('input#_password', PASSWORD)

        # Click on the login button
        page.click('input#submit-login')

        page.wait_for_load_state('load')

        page.goto('https://accounts.hetzner.com/invoice')

        # Wait for the first CSV link to be present
        csv_selector = 'a.btn-download[href*="/invoice/"][href$="/csv"]'
        page.wait_for_selector(csv_selector)

        # Get the URL of the first CSV link
        csv_link_url = page.query_selector(csv_selector).get_attribute('href')
        print(f"CSV Link URL: {csv_link_url}")

        with page.expect_download() as download_info:
            # Click the first CSV link
            page.click(csv_selector)

        download = download_info.value

        download.save_as("/tmp/" + download.suggested_filename)
        print(f"Download finished: {download.url}")

        browser.close()

if __name__ == "__main__":
    main()