commit fe6a314299b07495940ed99f5f99d1a3427676a9
Author: Jens Kristoffersson <jens.kristoffersson.se@gmail.com>
AuthorDate: Fri Aug 28 09:33:08 2026 +0200
Commit: Jens Kristoffersson <jens.kristoffersson.se@gmail.com>
CommitDate: Fri Aug 28 09:33:08 2026 +0200
Skriv om README för att vara sajt-agnostisk: ramverket (webui/flöden) är huvudfokus, 1177-exemplet är en tydligt markerad bilaga
---
README.md | 170 +++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 91 insertions(+), 79 deletions(-)
diff --git a/README.md b/README.md
index eb8b900..6d0e846 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,19 @@
-# Egenremiss RPA
+# RPA-verktyg
-Halvautomatisk hämtning av egenremisser från personal.1177.se.
+Generellt verktyg för webbläsar-automation byggt på Playwright, med en
+webbaserad flödesbyggare där du klickar ihop steg (gå till URL, klicka,
+skriv i fält, extrahera data, ladda ner filer, loopa över listor, spara
+till JSON/CSV, köra egna Python-script, ...) istället för att skriva kod
+för varje ny automation.
-Inloggning via BankID kräver din manuella approval i telefonen - det går
-inte att helautomatisera på ett säkert sätt. Skriptet öppnar en synlig
-webbläsare, väntar på att du loggar in, och tar sedan över: listar
-egenremisser, laddar ner ev. dokument, jämför mot förra körningen och
-notifierar om nytt/ändrat.
+Byggt för fall där inloggningen kräver manuell interaktion (BankID, 2FA,
+captcha) och därför inte kan helautomatiseras säkert: verktyget öppnar en
+synlig webbläsare, du loggar in en gång manuellt, och sessionen sparas i
+en persistent profil så du slipper göra om det varje körning.
+
+Repot innehåller dels det generella ramverket (webui + `rpa/`-paketet),
+dels ett fristående exempel på en färdig automation byggd med det
+(hämtning av egenremisser från personal.1177.se) - se sist i dokumentet.
## Setup
@@ -17,63 +24,32 @@ pip install -r requirements.txt
python -m playwright install chromium
```
-## Första körningen: hitta rätt selectors
-
-Jag har inte kunnat inspektera den inloggade sidans faktiska HTML-struktur
-(kräver ju BankID), så `rpa/scraper.py` och `rpa/config.py` bygger på
-rimliga men ovverifierade gissningar om länktexter och sidstruktur.
+## Kom igång: hitta rätt selectors för en ny sida
**Rekommenderat sätt: Playwright Codegen.** Den öppnar en webbläsare +
-ett inspector-fönster; klicka runt manuellt så genereras exakta
-selectors åt dig i realtid – inget gissningsarbete:
+ett inspector-fönster; klicka runt manuellt på sidan du vill automatisera
+så genereras exakta selectors åt dig i realtid – inget gissningsarbete:
```powershell
-python -m rpa.codegen
+python -m rpa.codegen <url>
```
-Den återanvänder samma profil (`data/browser_profile/`) som webui:t/`main.py`,
-så en giltig BankID-session följer med. Stäng ev. körande flöde i webui:t
-först (en Chromium-profilmapp kan bara användas av en process åt gången).
-Använd de genererade text-/CSS-värdena direkt i webui:ts steg (t.ex.
-"Klicka", "Skriv i textfält", "Lista poster") eller i `rpa/config.py`.
+Den återanvänder samma profil (`data/browser_profile/`) som webui:t, så
+en giltig inloggningssession följer med. Stäng ev. körande flöde i
+webui:t först (en Chromium-profilmapp kan bara användas av en process åt
+gången). Använd de genererade text-/CSS-värdena direkt i webui:ts steg
+(t.ex. "Klicka", "Skriv i textfält", "Lista poster").
-Alternativ (mer manuellt): `python -m rpa.discover` dumpar HTML +
-skärmdump av aktuell sida till `data/discover/` så du kan läsa strukturen
-själv:
+Alternativ (mer manuellt): `python -m rpa.discover` loggar in och låter
+dig, för varje sida du manuellt navigerar till, spara en HTML-dump +
+skärmdump i `data/discover/` genom att trycka Enter i terminalen - bra
+när du hellre vill läsa igenom den faktiska HTML-strukturen själv.
```powershell
python -m rpa.discover
```
-1. Godkänn BankID i telefonen när webbläsaren öppnas.
-2. Navigera manuellt till sidan med dina egenremisser.
-3. Tryck Enter i terminalen för att spara en HTML-dump + skärmdump i
- `data/discover/`.
-4. Öppna dumpen, hitta den exakta länktexten till egenremiss-sidan och
- listans faktiska HTML-struktur (tabell? ul/li? kort?).
-5. Uppdatera:
- - `rpa/config.py` → `REMISS_LINK_TEXT_CANDIDATES` med exakt länktext.
- - `rpa/scraper.py` → `list_egenremisser` selectorn `"main li, main tr, main article"`
- om listan har en annan struktur.
-
-## Vanlig körning
-
-```powershell
-python main.py
-```
-
-Sessionen sparas i `data/browser_profile/` (persistent Chromium-profil),
-så om den fortfarande är giltig nästa gång slipper du godkänna BankID igen.
-
-Resultat:
-- `data/state.json` - senaste kända lista, används för att upptäcka nytt/ändrat.
-- `data/downloads/` - nedladdade dokument/PDF:er kopplade till egenremisser.
-- Skrivbordsnotis + terminalutskrift vid nya/ändrade poster.
-
-## Webb-UI för att bygga flöden
-
-Istället för att koda steg direkt kan du bygga och köra flöden i en enkel
-lokal webbsida:
+## Webb-UI för att bygga och köra flöden
```powershell
python run_webui.py
@@ -81,14 +57,14 @@ python run_webui.py
Öppna sedan http://127.0.0.1:8765 i webbläsaren. Servern lyssnar bara på
127.0.0.1 (inte nätverket) eftersom den styr en riktig webbläsare mot din
-inloggade 1177-session.
+inloggade session.
I UI:t bygger du ett flöde som en lista av steg:
-- **Gå till URL** – navigerar (t.ex. `https://www.1177.se/`)
+- **Gå till URL** – navigerar (t.ex. `https://example.com/`)
- **Vänta (sekunder)** – fast paus
- **Vänta på att sidan laddas** – väntar på domcontentloaded
-- **Vänta på inloggning (BankID)** – pausar tills du godkänt BankID i telefonen
+- **Vänta på inloggning (BankID)** – pausar tills du godkänt inloggningen manuellt
- **Vänta på element** – pausar tills ett element via text/CSS/roll finns/syns
- **Klicka** – hittar ett element via text/CSS/roll och klickar
- **Skriv i textfält** – hittar ett fält via text/CSS/roll och skriver in text
@@ -114,6 +90,7 @@ I UI:t bygger du ett flöde som en lista av steg:
projektroten eller absolut), loggar dess stdout/stderr i körloggen och
kan spara dess stdout som en variabel (tolkas som JSON om möjligt,
annars som text). Flödet stoppas om scriptet avslutar med felkod.
+ Praktiskt för egen efterbehandling av data som extraherats i flödet.
- **Ta skärmdump** – sparar en skärmdump i `data/screenshots/` (bra för
felsökning av flöden)
- **Lista poster** – hittar alla element som matchar en CSS-selector och
@@ -123,12 +100,9 @@ I UI:t bygger du ett flöde som en lista av steg:
aktuell post
- **Ladda ner** – klickar ett element och sparar filen i `data/downloads/`
-Det motsvarar din ursprungliga pseudokod:
-
-```
-Gå till URL → Vänta på att sidan laddas → Klicka → Klicka
-→ Lista poster → Loop { Klicka, Ladda ner, Vänta 8 }
-```
+Ett typiskt flöde: `Gå till URL → Vänta på inloggning → Klicka → Lista
+poster → Loop { Läs text till variabel, Lägg till i lista, Ladda ner } →
+Spara variabel som CSV`.
Flöden sparas som JSON i `data/flows/<namn>.json` – redigerbara även för
hand om du vill. "Kör flöde" sparar automatiskt och kör sedan i en synlig
@@ -159,32 +133,70 @@ python -m rpa.show_trace # senaste sparade trace
python -m rpa.show_trace <run_id> # en specifik körning
```
-Precis som med `main.py` vet jag inte i förväg exakt vilken text/selector
-som matchar dina riktiga knappar och listor på 1177 – kör
-`python -m rpa.codegen` (se ovan) för att ta reda på dem, och använd samma
-värden i UI:ts steg.
+## Persistent inloggning
+
+Sessionen sparas i `data/browser_profile/` (persistent Chromium-profil),
+så om den fortfarande är giltig nästa gång körs behöver du inte logga in
+igen. Det gäller oavsett om flödet körs via webui:t, `python -m
+rpa.codegen`, eller ett eget script byggt på `rpa/browser.py`.
+
+`rpa/auth.py` innehåller ett generellt mönster för att vänta ut en manuell
+inloggning: `wait_for_login(page, timeout_s)` pollar sidan tills någon av
+`config.LOGGED_IN_INDICATORS` (fri textmatchning) syns, eller ger upp efter
+en timeout. Anpassa `config.START_URL` och `config.LOGGED_IN_INDICATORS`
+per sajt.
## Schemaläggning
-Kör manuellt vid behov (`python main.py`). Vill du schemalägga via Windows
-Task Scheduler senare: tänk på att BankID-godkännande krävs varje gång
-sessionen i `data/browser_profile/` har gått ut, så helt obevakad körning
-fungerar bara så länge sessionen är giltig.
+Kör manuellt vid behov. Vill du schemalägga via Windows Task Scheduler:
+tänk på att manuell inloggning (BankID/2FA) krävs varje gång sessionen i
+`data/browser_profile/` har gått ut, så helt obevakad körning fungerar
+bara så länge sessionen är giltig.
+
+## Bygga en egen fristående automation
+
+Utöver webui:ts JSON-flöden går det förstås bra att skriva ett eget
+Python-script mot samma byggstenar i `rpa/`:
+
+- `rpa/browser.py` – `launch_context()`/`get_page()`, den persistenta
+ Chromium-profilen.
+- `rpa/auth.py` – vänta ut manuell inloggning.
+- `rpa/config.py` – gemensamma sökvägar och sajt-specifika inställningar
+ (URL, textindikatorer för inloggning, etc.) - detta är filen du främst
+ anpassar per ny automation.
+
+`main.py` + `rpa/scraper.py` + `rpa/state.py` + `rpa/notify.py` +
+`rpa/discover.py` är ett komplett **exempel** byggt på detta: hämtning av
+egenremisser från personal.1177.se, med diff mot förra körningen
+(`state.py`) och skrivbordsnotis vid nytt/ändrat (`notify.py`). Kör det
+med:
+
+```powershell
+python main.py
+```
+
+Resultat: `data/state.json` (senaste kända lista), `data/downloads/`
+(nedladdade dokument), skrivbordsnotis + terminalutskrift vid
+nya/ändrade poster.
+
+Använd det som mall när du bygger en ny fristående automation för en
+annan sajt - byt ut `scraper.py`s sid-specifika logik, `config.py`s
+URL/textindikatorer, och `notify.py`s meddelandetext. Behöver du inte
+diff/notis-mönstret alls räcker det oftast med ett flöde i webui:t.
## Att tänka på
-- Respektera 1177:s användarvillkor - detta är byggt för att hämta din
- egen personliga information, inte för massuttag eller belastning.
- Skriptet kör med synlig, "vanlig" webbläsare utan bot-detection-kringgång.
- Lägg gärna in rimliga pauser om du kör ofta.
+- Respektera användarvillkoren för sajten du automatiserar - detta är
+ byggt för att hämta din egen personliga information, inte för
+ massuttag eller belastning. Webbläsaren körs synlig och "vanlig" utan
+ bot-detection-kringgång. Lägg gärna in rimliga pauser om du kör ofta.
- Spara inte `data/browser_profile/`, `data/downloads/`, `data/traces/`,
`data/screenshots/` eller `data/exports/` i något delat eller
- versionshanterat ställe - de kan innehålla inloggningssession och
- personlig hälsoinformation (traces och skärmdumpar visar sidans faktiska
- innehåll steg för steg, och exports kan innehålla data du samlat in
- från sidan via "Lägg till i lista"/"Spara variabel").
+ versionshanterat ställe - de kan innehålla inloggningssessioner och
+ personlig/känslig information beroende på vilken sajt du automatiserar
+ (traces och skärmdumpar visar sidans faktiska innehåll steg för steg,
+ och exports kan innehålla data du samlat in från sidan). `data/` ligger
+ redan i `.gitignore`.
- "Kör Python-script" kör vad som helst du pekar ut, med samma rättigheter
som webui-processen - bara för egna, betrodda script, inte för att köra
kod du inte litar på.
-- `data/` ligger i `.gitignore` och ska inte versionshanteras alls, av
- samma anledning som ovan.