Skip to main content

Automated form filling and mapping tool with LLM integration

Project description

🧠 FORMAP - Advanced Form Mapper & Auto-Filler

[English below] Zaawansowane narzędzie do mapowania i automatycznego wypełniania formularzy internetowych przy użyciu Playwright i sztucznej inteligencji.

✨ Funkcje

  • 🔍 Automatyczne wykrywanie pól formularza z zaawansowanym mapowaniem
  • 🤖 Integracja z lokalnym modelem językowym (LLM) dla lepszego rozumienia formularzy
  • 📁 Obsługa załączników (CV, listy motywacyjne, itp.)
  • 🎯 Inteligentne dopasowywanie etykiet do pól formularza
  • 💾 Zapis mapowania pól do pliku JSON
  • 🚀 Automatyczne wypełnianie formularzy na podstawie zapisanego mapowania
  • 🔒 Obsługa wszystkich standardowych pól formularza (tekst, wybór, radio, checkbox, pliki, itp.)
  • 🐍 Prosty interfejs wiersza poleceń i API Pythona

🧠 FORMAP - Advanced Form Mapper & Auto-Filler

Automatically map and fill web forms with ease using Playwright and AI.

✨ Features

  • 🔍 Automatic form field detection with advanced mapping
  • 🤖 Local Language Model (LLM) integration for better form understanding
  • 📁 File upload support (CVs, cover letters, etc.)
  • 🎯 Smart label-to-field association
  • 💾 Save field mappings to JSON files
  • 🚀 Automatically fill forms using saved mappings
  • 🔒 Supports all standard form fields (text, select, radio, checkbox, file uploads, etc.)
  • 🐍 Simple CLI and Python API

🚀 Szybki start / Quick Start

Wymagania / Prerequisites

  • Python 3.8+
  • Git (do sklonowania repozytorium / for cloning the repository)
  • Poetry (do zarządzania zależnościami / for dependency management)

Instalacja / Installation

  1. Zainstaluj Poetry (jeśli nie jest zainstalowany) / Install Poetry (if not installed):

    curl -sSL https://install.python-poetry.org | python3 -
    
  2. Sklonuj repozytorium / Clone the repository:

    git clone https://github.com/yourusername/formap.git
    cd formap
    
  3. Skonfiguruj środowisko / Set up the environment:

    # Zainstaluj zależności
    # Install dependencies
    poetry install
    
    # Zainstaluj przeglądarkę do testów
    # Install browser for testing
    poetry run playwright install
    

    Zainstaluj przeglądarki Playwright

    Install Playwright browsers

    python -m playwright install

    
    

🛠️ Użycie / Usage

1. Mapowanie pól formularza / Map Form Fields

Aby zmapować pola formularza / To map the fields of a form:

# Aktywuj środowisko wirtualne jeśli nieaktywne
# Activate virtual environment if not already activated
source venv/bin/activate

# Uruchom mapowanie
# Run the mapper
python form-mapper/map_fields.py https://przykladowa-strona.pl/logowanie

Włącz szczegółowe logowanie / Enable debug logging

poetry run formap --debug detect https://example.com/form


### 2. Wypełnianie formularza / Fill a Form

Aby wypełnić formularz używając danych z pliku / To fill a form using data file:

```bash
# Wypełnij formularz używając danych z pliku
# Fill form using data file
poetry run formap fill https://example.com/form --data form_data.json

# Użyj niestandardowego mapowania pól / Use custom field mapping
poetry run formap fill https://example.com/form --data form_data.json --mapping form_map.json

# Uruchom w trybie bezinterakcyjnym / Run in headless mode
poetry run formap fill https://example.com/form --data form_data.json --headless

3. Użycie z kodu Pythona / Using from Python Code

import asyncio
from formap import FormDetector, FormFiller

async def main():
    # Mapowanie formularza / Form mapping
    async with FormDetector() as detector:
        fields = await detector.detect("https://example.com/form")
        print(f"Znaleziono {len(fields)} pól formularza")
    
    # Wypełnianie formularza / Form filling
    async with FormFiller() as filler:
        await filler.fill(
            "https://example.com/form",
            data={"username": "test", "email": "test@example.com"},
            mapping=fields,
            headless=True
        )

if __name__ == "__main__":
    asyncio.run(main())

📋 Przykłady użycia / Usage Examples

Przykład 1: Logowanie / Example 1: Login Form

# Mapowanie formularza logowania
# Mapping a login form
poetry run formap detect https://example.com/login
# Po zapisaniu mapowania, wypełnij formularz
# After saving the mapping, fill the form
poetry run formap fill https://example.com/login --data login_data.json

Przykład 2: Rejestracja / Example 2: Registration Form

# Mapowanie formularza rejestracji
# Mapping a registration form
poetry run formap detect https://example.com/register
# Wypełnij formularz danymi
# Fill the form with data
poetry run formap fill https://example.com/register --data register_data.json

Przykład 3: Formularz kontaktowy / Example 3: Contact Form

# Mapowanie formularza kontaktowego
# Mapping a contact form
poetry run formap detect https://example.com/contact
# Wypełnij i wyślij formularz
# Fill and submit the form
poetry run formap fill https://example.com/contact --data contact_data.json

🐳 Uruchamianie w Dockerze / Docker Support

Możesz również uruchomić FORMAP używając Dockera / You can also run FORMAP using Docker:

# Zbuduj obraz Dockera / Build the Docker image
docker build -t formap .

# Uruchom mapowanie / Run the mapper
docker run -it --rm -v $(pwd):/app formap poetry run formap detect https://example.com/form

# Uruchom wypełnianie / Run the filler
docker run -it --rm -v $(pwd):/app formap poetry run formap fill https://example.com/form --data form_data.json

📁 Project Structure

form-mapper/
├── Dockerfile           # Docker configuration
├── Makefile            # Common commands
├── README.md           # This file
├── requirements.txt     # Python dependencies
├── map_fields.py       # Form field mapping script
└── fill_form.py        # Form filling script

💡 Wskazówki / Tips

  • Upewnij się, że wszystkie wymagane pola są wypełnione przed zapisaniem mapowania.
  • Możesz edytować plik form_map.json ręcznie, aby dostosować mapowanie.
  • Użyj opcji --headless aby uruchomić przeglądarkę w trybie bezokienkowym.

🤝 Współtworzenie / Contributing

Wkład jest mile widziany! Zapraszamy do przesyłania Pull Requestów. / Contributions are welcome! Please feel free to submit a Pull Request.

📄 Licencja / License

Ten projekt jest dostępny na licencji MIT - zobacz plik LICENSE aby uzyskać więcej informacji. / This project is licensed under the MIT License - see the LICENSE file for details.

Oto pełna struktura projektu do mapowania i wypełniania formularzy za pomocą Playwright, w stylu MVP z Mistral 7B, z kompletem:

  • Makefile do uruchamiania zadań
  • Dockerfile do konteneryzacji
  • docker-compose.yml do lokalnego uruchamiania
  • README.md z instrukcją

📁 Struktura projektu:

form-mapper/
├── Dockerfile
├── Makefile
├── README.md
├── docker-compose.yml
├── map_fields.py
├── fill_form.py
├── requirements.txt
└── example.env

📄 map_fields.py i fill_form.py

(Już masz je wcześniej — kopiujesz z poprzedniej wiadomości.)


📄 requirements.txt

playwright==1.44.0

📄 Dockerfile

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt && \
    playwright install --with-deps

COPY . .

CMD ["bash"]

📄 docker-compose.yml

version: '3.8'

services:
  formmapper:
    build: .
    container_name: formmapper
    environment:
      - PYTHONUNBUFFERED=1
    volumes:
      - .:/app
    entrypoint: ["tail", "-f", "/dev/null"]  # Do debugowania interaktywnego

(możesz zmienić entrypoint, by odpalało konkretne polecenie, np. python map_fields.py)


📄 Makefile

.PHONY: map fill up build shell

map:
	python map_fields.py

fill:
	python fill_form.py

build:
	docker-compose build

up:
	docker-compose up -d

shell:
	docker-compose exec formmapper bash

📄 example.env

URL=https://example.com
EMAIL=test@example.com
USERNAME=jan.kowalski
PASSWORD=tajne123

(Można potem podciągać zmienne do fill_form.py z os.getenv.)


📄 README.md

# 🧠 Form Mapper & Auto-Filler (Playwright + Mistral 7B-style)

Ten projekt automatycznie:
1. Mapuje formularze HTML przez klawisz `Tab`
2. Tworzy plik JSON z XPath i typami pól
3. Na podstawie mapy automatycznie wypełnia formularze

## 🔧 Wymagania

- Python 3.11+
- Docker (opcjonalnie)

## 🐍 Lokalne uruchomienie

### Instalacja
```bash
pip install -r requirements.txt
playwright install

Mapowanie pól

make map

Wypełnianie formularza

make fill

🐳 Uruchomienie w Dockerze

Budowanie kontenera

make build

Włączenie środowiska

make up
make shell  # potem np. python map_fields.py

📂 Pliki

  • map_fields.py – mapa formularzy przez Tab
  • fill_form.py – wypełnianie pól wg JSON
  • form_map.json – wynik mapowania
  • example.env – przykładowe dane

📌 Autor

Projekt edukacyjny inspirowany użyciem LLM (np. Mistral 7B) do automatyzacji formularzy.


---

Chcesz, bym dodał możliwość odczytu danych z `.env`, automatyczne rozpoznawanie checkboxów, czy też interaktywny CLI do wprowadzania danych?

Oto prosty, dwuczęściowy skrypt w Pythonie używający Playwright, który:

  1. Symuluje przechodzenie przez pola formularza przy pomocy klawisza Tab, zapisując kolejne XPathy i typy pól (np. input, button, select).
  2. Zapisuje mapę pól do pliku JSON, która potem może być użyta do automatycznego wypełniania formularza.

⚠️ Dostosowany do ograniczeń Mistral 7B: nie robi analizy semantycznej strony, tylko czysto techniczne mapowanie po Tab.


📦 Wymagania:

Zainstaluj Playwright:

pip install playwright
playwright install

🧠 Część 1: Mapowanie pól przez Tab i zapis do JSON

# map_fields.py
import json
import asyncio
from playwright.async_api import async_playwright

async def map_form_fields(url: str, output_json: str = "form_map.json"):
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto(url)

        print(f"[INFO] Odwiedzono stronę: {url}")

        mapped_fields = []
        visited_elements = set()

        for i in range(50):  # maksymalnie 50 tabów
            await page.keyboard.press("Tab")
            await page.wait_for_timeout(200)

            active = await page.evaluate_handle("document.activeElement")
            tag = await active.evaluate("el => el.tagName.toLowerCase()")
            typ = await active.evaluate("el => el.type || ''")
            name = await active.evaluate("el => el.name || ''")
            id_attr = await active.evaluate("el => el.id || ''")

            xpath = await page.evaluate('''
                el => {
                    function getXPath(el) {
                        if (el.tagName === 'HTML')
                            return '/html';
                        if (el === document.body)
                            return '/html/body';
                        var ix = 0;
                        var siblings = el.parentNode.childNodes;
                        for (var i = 0; i < siblings.length; i++) {
                            var sibling = siblings[i];
                            if (sibling === el)
                                return getXPath(el.parentNode) + '/' + el.tagName.toLowerCase() + '[' + (ix+1) + ']';
                            if (sibling.nodeType === 1 && sibling.tagName === el.tagName)
                                ix++;
                        }
                    }
                    return getXPath(el);
                }
            ''', active)

            if xpath not in visited_elements:
                visited_elements.add(xpath)
                mapped_fields.append({
                    "tag": tag,
                    "type": typ,
                    "name": name,
                    "id": id_attr,
                    "xpath": xpath,
                })

        with open(output_json, "w") as f:
            json.dump(mapped_fields, f, indent=2)
            print(f"[INFO] Zapisano mapę formularza do: {output_json}")

        await browser.close()

if __name__ == "__main__":
    url = "https://przyklad.pl"  # <- PODAJ PRAWIDŁOWY ADRES STRONY
    asyncio.run(map_form_fields(url))

📝 Część 2: Wypełnianie formularza według mapy

# fill_form.py
import json
import asyncio
from playwright.async_api import async_playwright

async def fill_form(url: str, json_map: str, values: dict):
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto(url)

        with open(json_map, "r") as f:
            fields = json.load(f)

        for field in fields:
            xpath = field["xpath"]
            typ = field["type"]
            tag = field["tag"]

            if typ in ["text", "email", "password", "search", "tel", "url"] or tag == "textarea":
                value = values.get(field["name"] or field["id"] or xpath, "test")
                try:
                    el = await page.wait_for_selector(f"xpath={xpath}", timeout=1000)
                    await el.fill(value)
                except Exception as e:
                    print(f"[WARN] Nie udało się wypełnić pola {xpath}: {e}")

        await page.wait_for_timeout(3000)
        await browser.close()

if __name__ == "__main__":
    values = {
        "email": "test@example.com",
        "username": "jan.kowalski",
        "password": "tajne123"
        # dodaj klucze na podstawie mapy
    }
    url = "https://przyklad.pl"  # <- PODAJ TĘ SAMĄ STRONĘ
    asyncio.run(fill_form(url, "form_map.json", values))

✅ Jak tego używać?

  1. Krok 1: Uruchom map_fields.py, by stworzyć mapę formularza.
  2. Krok 2: Przejrzyj form_map.json i podaj odpowiednie wartości w fill_form.py.
  3. Krok 3: Uruchom fill_form.py, by automatycznie wypełnić pola.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

formap-0.1.1.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

formap-0.1.1-py3-none-any.whl (17.3 kB view details)

Uploaded Python 3

File details

Details for the file formap-0.1.1.tar.gz.

File metadata

  • Download URL: formap-0.1.1.tar.gz
  • Upload date:
  • Size: 19.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.3 CPython/3.11.12 Linux/6.14.9-300.fc42.x86_64

File hashes

Hashes for formap-0.1.1.tar.gz
Algorithm Hash digest
SHA256 1175a1503be0faba639fb57cb514b9045e26244d97fb23e1e1e3ec47b7802515
MD5 fae28d11c0ffe90c01cd4b3b44052cb7
BLAKE2b-256 024c8913eb3ac1b7519ca05d55efac603a73e1deff5514291bca370c7e1fdbbc

See more details on using hashes here.

File details

Details for the file formap-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: formap-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 17.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.3 CPython/3.11.12 Linux/6.14.9-300.fc42.x86_64

File hashes

Hashes for formap-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8f86b1c348eb4777476d9f6ce7452eae560f60058d9b3d5808b83c294237d81e
MD5 7509cf54730c63c3df7c21c9d8031cf4
BLAKE2b-256 26f292be1351b323f8113c038ea0363250a53135022f3fbbc4b0a1cd04010879

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page