Add TinDog auto-like Selenium bot, tests, e2e harness and wiki #2

Merged
Tirsvad merged 1 commits from feature/tinder-auto-like-bot into main 2026-11-03 03:48:42 +01:00
4 changed files with 35 additions and 35 deletions
Showing only changes of commit a1b9e7caa6 - Show all commits
+2 -2
View File
@@ -6,8 +6,8 @@ that logs in to **TinDog** (the course's Tinder clone,
It is a modernised version of the
[earlier solution](https://github.com/Tirsvad/udemy.python.100-days-of-code/tree/main/day-50-tinder-auto-find-match).
Wiki (what each step teaches): [English](docs/wiki/en/Home.md) ·
[Dansk](docs/wiki/da/Home.md) · [Bahasa Malaysia](docs/wiki/ms/Home.md)
Wiki (what each step teaches): [English](docs/wiki/Home.md) ·
[Dansk](docs/wiki/Home-da.md) · [Bahasa Malaysia](docs/wiki/Home-ms.md)
> Be honest with the people you date: tell them you automate your swiping.
> TinDog allows 20 likes a day, Tinder 100 on the free tier.
+11 -11
View File
@@ -1,45 +1,45 @@
# Dag 50 - Tinder auto find match (Dansk)
[English](../en/Home.md) · [Bahasa Malaysia](../ms/Home.md)
[English](Home) · [Bahasa Malaysia](Home-ms)
Mål: automatisér login og "like" af profiler på TinDog med Python og Selenium.
Etik først: fortæl din partner, at du automatiserer, og respektér den daglige
grænse (TinDog 20, Tinder gratis 100).
## Trin 1 - Se siden igennem manuelt
![Forside](../../screenshots/01-home.png)
![Forside](../screenshots/01-home.png)
**Det lærte vi:** klik først selv igennem og notér, hvilke elementer koden skal
ramme. Gode locators kommer af at kende siden.
## Trin 2 - Gå til login-siden
![Login-vindue](../../screenshots/02-login-modal.png)
![Login-vindue](../screenshots/02-login-modal.png)
**Det lærte vi:** `driver.get`, XPath-locators (`locators.py`) og at vente med
`WebDriverWait` + `element_to_be_clickable` i stedet for faste `sleep`. Det
undgår `NoSuchElementException` på langsomme sider.
## Trin 3 - Facebook-popup
![Facebook-popup](../../screenshots/03-facebook-popup.png)
![Facebook-popup](../screenshots/03-facebook-popup.png)
**Det lærte vi:** login åbner et ekstra browservindue. Vi skifter med
`driver.window_handles` og `switch_to.window`, udfylder formularen og skifter
tilbage. Loginoplysninger ligger i miljøvariabler, aldrig i koden.
## Trin 4 - Luk alle forespørgsler
Lokation ([04](../../screenshots/04-location.png)), notifikationer
([05](../../screenshots/05-notifications.png)), cookies
([06](../../screenshots/06-cookies.png)).
Lokation ([04](../screenshots/04-location.png)), notifikationer
([05](../screenshots/05-notifications.png)), cookies
([06](../screenshots/06-cookies.png)).
![Cookies](../../screenshots/06-cookies.png)
![Cookies](../screenshots/06-cookies.png)
**Det lærte vi:** modale popups blokerer alt bagved. Vi klikker ALLOW, NOT
INTERESTED og I ACCEPT og springer en popup over, hvis den ikke dukker op
(`TimeoutException` håndteres og logges).
## Trin 5 - Tryk Like
![Liker](../../screenshots/07-liking.png)
![Match-popup](../../screenshots/08-match-popup.png)
![Liker](../screenshots/07-liking.png)
![Match-popup](../screenshots/08-match-popup.png)
**Det lærte vi:** undtagelser som styring af en ustabil brugerflade:
`NoSuchElementException` betyder "indlæser stadig, vent 2 sek. og prøv igen";
@@ -47,7 +47,7 @@ INTERESTED og I ACCEPT og springer en popup over, hvis den ikke dukker op
BACK TO TINDER". En pause mellem likes gør, at botten ikke ligner en bot.
Løkken stopper ved den indstillede grænse.
![Færdig](../../screenshots/09-done.png)
![Færdig](../screenshots/09-done.png)
## Modernisering ift. den tidligere løsning
- `src/`-pakke med én funktion pr. trin i stedet for én klasse med `sleep`.
+11 -11
View File
@@ -1,19 +1,19 @@
# Hari 50 - Tinder auto find match (Bahasa Malaysia)
[English](../en/Home.md) · [Dansk](../da/Home.md)
[English](Home) · [Dansk](Home-da)
Matlamat: mengautomasikan log masuk dan "like" profil di TinDog menggunakan
Python dan Selenium. Etika dahulu: beritahu pasangan anda bahawa anda
menggunakan automasi, dan patuhi had harian (TinDog 20, Tinder percuma 100).
## Langkah 1 - Lihat laman web secara manual
![Laman utama](../../screenshots/01-home.png)
![Laman utama](../screenshots/01-home.png)
**Apa yang kita pelajari:** sebelum menulis kod, klik sendiri dan catat elemen
yang perlu disasarkan. Locator yang baik datang daripada mengenali halaman.
## Langkah 2 - Pergi ke halaman log masuk
![Modal log masuk](../../screenshots/02-login-modal.png)
![Modal log masuk](../screenshots/02-login-modal.png)
**Apa yang kita pelajari:** `driver.get`, locator XPath (`locators.py`) dan
menunggu dengan `WebDriverWait` + `element_to_be_clickable` dan bukannya
@@ -21,7 +21,7 @@ menunggu dengan `WebDriverWait` + `element_to_be_clickable` dan bukannya
perlahan.
## Langkah 3 - Tetingkap timbul Facebook
![Tetingkap Facebook](../../screenshots/03-facebook-popup.png)
![Tetingkap Facebook](../screenshots/03-facebook-popup.png)
**Apa yang kita pelajari:** log masuk membuka tetingkap pelayar kedua. Kita
bertukar dengan `driver.window_handles` dan `switch_to.window`, mengisi borang,
@@ -29,19 +29,19 @@ kemudian kembali. Kelayakan disimpan dalam pemboleh ubah persekitaran, bukan
dalam kod.
## Langkah 4 - Tutup semua permintaan
Lokasi ([04](../../screenshots/04-location.png)), pemberitahuan
([05](../../screenshots/05-notifications.png)), kuki
([06](../../screenshots/06-cookies.png)).
Lokasi ([04](../screenshots/04-location.png)), pemberitahuan
([05](../screenshots/05-notifications.png)), kuki
([06](../screenshots/06-cookies.png)).
![Kuki](../../screenshots/06-cookies.png)
![Kuki](../screenshots/06-cookies.png)
**Apa yang kita pelajari:** tetingkap modal menghalang semua yang di
belakangnya. Kita klik ALLOW, NOT INTERESTED dan I ACCEPT, dan langkau yang
tidak muncul (`TimeoutException` dikendalikan dan dilog).
## Langkah 5 - Tekan Like
![Like](../../screenshots/07-liking.png)
![Tetingkap padanan](../../screenshots/08-match-popup.png)
![Like](../screenshots/07-liking.png)
![Tetingkap padanan](../screenshots/08-match-popup.png)
**Apa yang kita pelajari:** pengecualian sebagai kawalan aliran untuk UI yang
tidak stabil: `NoSuchElementException` bermaksud "masih memuat, tunggu 2 saat
@@ -49,7 +49,7 @@ dan cuba lagi"; `ElementClickInterceptedException` bermaksud "tetingkap padanan
menghalang, klik BACK TO TINDER". Jeda antara "like" menjadikan bot kurang
ketara. Gelung berhenti pada had yang ditetapkan.
![Selesai](../../screenshots/09-done.png)
![Selesai](../screenshots/09-done.png)
## Pemodenan berbanding penyelesaian terdahulu
- Pakej `src/` dengan satu fungsi bagi setiap langkah dan bukannya satu kelas
+11 -11
View File
@@ -1,19 +1,19 @@
# Day 50 - Tinder auto find match (English)
[Dansk](../da/Home.md) · [Bahasa Malaysia](../ms/Home.md)
[Dansk](Home-da) · [Bahasa Malaysia](Home-ms)
Goal: automate logging in and liking profiles on TinDog with Python and
Selenium. Ethics first: tell your partner you automate, and respect the daily
limit (TinDog 20, Tinder free tier 100).
## Step 1 - Look at the site by hand
![Home](../../screenshots/01-home.png)
![Home](../screenshots/01-home.png)
**What we gained:** before coding, click through manually and note which
elements you must target. Good locators come from looking at the page first.
## Step 2 - Navigate to the login page
![Login modal](../../screenshots/02-login-modal.png)
![Login modal](../screenshots/02-login-modal.png)
**What we gained:** `driver.get`, locating buttons with XPath
(`locators.py`) and waiting for them with `WebDriverWait` +
@@ -21,26 +21,26 @@ elements you must target. Good locators come from looking at the page first.
`NoSuchElementException` on slow pages.
## Step 3 - The Facebook pop-up
![Facebook popup](../../screenshots/03-facebook-popup.png)
![Facebook popup](../screenshots/03-facebook-popup.png)
**What we gained:** the login opens a second browser window. We switch with
`driver.window_handles` and `switch_to.window`, fill the form, then switch back.
Credentials live in environment variables, never in code.
## Step 4 - Dismiss all requests
Location ([04](../../screenshots/04-location.png)), notifications
([05](../../screenshots/05-notifications.png)), cookies
([06](../../screenshots/06-cookies.png)).
Location ([04](../screenshots/04-location.png)), notifications
([05](../screenshots/05-notifications.png)), cookies
([06](../screenshots/06-cookies.png)).
![Cookies](../../screenshots/06-cookies.png)
![Cookies](../screenshots/06-cookies.png)
**What we gained:** modal pop-ups block everything behind them. We click ALLOW,
NOT INTERESTED and I ACCEPT, and skip a pop-up that does not appear
(`TimeoutException` is handled and logged).
## Step 5 - Hit Like
![Liking](../../screenshots/07-liking.png)
![Match popup](../../screenshots/08-match-popup.png)
![Liking](../screenshots/07-liking.png)
![Match popup](../screenshots/08-match-popup.png)
**What we gained:** exception handling as control flow for a flaky UI:
`NoSuchElementException` means "still loading, wait 2 s and retry";
@@ -48,7 +48,7 @@ NOT INTERESTED and I ACCEPT, and skip a pop-up that does not appear
BACK TO TINDER". A pause between likes keeps the bot from looking like a bot.
The loop stops at the configured limit.
![Done](../../screenshots/09-done.png)
![Done](../screenshots/09-done.png)
## Modernisation compared with the earlier solution
- `src/` package with one function per step instead of one class with `sleep`.