Add TinDog auto-like Selenium bot, tests, e2e harness and wiki #2
@@ -6,8 +6,8 @@ that logs in to **TinDog** (the course's Tinder clone,
|
|||||||
It is a modernised version of the
|
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).
|
[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) ·
|
Wiki (what each step teaches): [English](docs/wiki/Home.md) ·
|
||||||
[Dansk](docs/wiki/da/Home.md) · [Bahasa Malaysia](docs/wiki/ms/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.
|
> 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.
|
> TinDog allows 20 likes a day, Tinder 100 on the free tier.
|
||||||
|
|||||||
@@ -1,45 +1,45 @@
|
|||||||
# Dag 50 - Tinder auto find match (Dansk)
|
# 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.
|
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
|
Etik først: fortæl din partner, at du automatiserer, og respektér den daglige
|
||||||
grænse (TinDog 20, Tinder gratis 100).
|
grænse (TinDog 20, Tinder gratis 100).
|
||||||
|
|
||||||
## Trin 1 - Se siden igennem manuelt
|
## Trin 1 - Se siden igennem manuelt
|
||||||

|

|
||||||
|
|
||||||
**Det lærte vi:** klik først selv igennem og notér, hvilke elementer koden skal
|
**Det lærte vi:** klik først selv igennem og notér, hvilke elementer koden skal
|
||||||
ramme. Gode locators kommer af at kende siden.
|
ramme. Gode locators kommer af at kende siden.
|
||||||
|
|
||||||
## Trin 2 - Gå til login-siden
|
## Trin 2 - Gå til login-siden
|
||||||

|

|
||||||
|
|
||||||
**Det lærte vi:** `driver.get`, XPath-locators (`locators.py`) og at vente med
|
**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
|
`WebDriverWait` + `element_to_be_clickable` i stedet for faste `sleep`. Det
|
||||||
undgår `NoSuchElementException` på langsomme sider.
|
undgår `NoSuchElementException` på langsomme sider.
|
||||||
|
|
||||||
## Trin 3 - Facebook-popup
|
## Trin 3 - Facebook-popup
|
||||||

|

|
||||||
|
|
||||||
**Det lærte vi:** login åbner et ekstra browservindue. Vi skifter med
|
**Det lærte vi:** login åbner et ekstra browservindue. Vi skifter med
|
||||||
`driver.window_handles` og `switch_to.window`, udfylder formularen og skifter
|
`driver.window_handles` og `switch_to.window`, udfylder formularen og skifter
|
||||||
tilbage. Loginoplysninger ligger i miljøvariabler, aldrig i koden.
|
tilbage. Loginoplysninger ligger i miljøvariabler, aldrig i koden.
|
||||||
|
|
||||||
## Trin 4 - Luk alle forespørgsler
|
## Trin 4 - Luk alle forespørgsler
|
||||||
Lokation ([04](../../screenshots/04-location.png)), notifikationer
|
Lokation ([04](../screenshots/04-location.png)), notifikationer
|
||||||
([05](../../screenshots/05-notifications.png)), cookies
|
([05](../screenshots/05-notifications.png)), cookies
|
||||||
([06](../../screenshots/06-cookies.png)).
|
([06](../screenshots/06-cookies.png)).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Det lærte vi:** modale popups blokerer alt bagved. Vi klikker ALLOW, NOT
|
**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
|
INTERESTED og I ACCEPT og springer en popup over, hvis den ikke dukker op
|
||||||
(`TimeoutException` håndteres og logges).
|
(`TimeoutException` håndteres og logges).
|
||||||
|
|
||||||
## Trin 5 - Tryk Like
|
## Trin 5 - Tryk Like
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
**Det lærte vi:** undtagelser som styring af en ustabil brugerflade:
|
**Det lærte vi:** undtagelser som styring af en ustabil brugerflade:
|
||||||
`NoSuchElementException` betyder "indlæser stadig, vent 2 sek. og prøv igen";
|
`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.
|
BACK TO TINDER". En pause mellem likes gør, at botten ikke ligner en bot.
|
||||||
Løkken stopper ved den indstillede grænse.
|
Løkken stopper ved den indstillede grænse.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Modernisering ift. den tidligere løsning
|
## Modernisering ift. den tidligere løsning
|
||||||
- `src/`-pakke med én funktion pr. trin i stedet for én klasse med `sleep`.
|
- `src/`-pakke med én funktion pr. trin i stedet for én klasse med `sleep`.
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
# Hari 50 - Tinder auto find match (Bahasa Malaysia)
|
# 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
|
Matlamat: mengautomasikan log masuk dan "like" profil di TinDog menggunakan
|
||||||
Python dan Selenium. Etika dahulu: beritahu pasangan anda bahawa anda
|
Python dan Selenium. Etika dahulu: beritahu pasangan anda bahawa anda
|
||||||
menggunakan automasi, dan patuhi had harian (TinDog 20, Tinder percuma 100).
|
menggunakan automasi, dan patuhi had harian (TinDog 20, Tinder percuma 100).
|
||||||
|
|
||||||
## Langkah 1 - Lihat laman web secara manual
|
## Langkah 1 - Lihat laman web secara manual
|
||||||

|

|
||||||
|
|
||||||
**Apa yang kita pelajari:** sebelum menulis kod, klik sendiri dan catat elemen
|
**Apa yang kita pelajari:** sebelum menulis kod, klik sendiri dan catat elemen
|
||||||
yang perlu disasarkan. Locator yang baik datang daripada mengenali halaman.
|
yang perlu disasarkan. Locator yang baik datang daripada mengenali halaman.
|
||||||
|
|
||||||
## Langkah 2 - Pergi ke halaman log masuk
|
## Langkah 2 - Pergi ke halaman log masuk
|
||||||

|

|
||||||
|
|
||||||
**Apa yang kita pelajari:** `driver.get`, locator XPath (`locators.py`) dan
|
**Apa yang kita pelajari:** `driver.get`, locator XPath (`locators.py`) dan
|
||||||
menunggu dengan `WebDriverWait` + `element_to_be_clickable` dan bukannya
|
menunggu dengan `WebDriverWait` + `element_to_be_clickable` dan bukannya
|
||||||
@@ -21,7 +21,7 @@ menunggu dengan `WebDriverWait` + `element_to_be_clickable` dan bukannya
|
|||||||
perlahan.
|
perlahan.
|
||||||
|
|
||||||
## Langkah 3 - Tetingkap timbul Facebook
|
## Langkah 3 - Tetingkap timbul Facebook
|
||||||

|

|
||||||
|
|
||||||
**Apa yang kita pelajari:** log masuk membuka tetingkap pelayar kedua. Kita
|
**Apa yang kita pelajari:** log masuk membuka tetingkap pelayar kedua. Kita
|
||||||
bertukar dengan `driver.window_handles` dan `switch_to.window`, mengisi borang,
|
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.
|
dalam kod.
|
||||||
|
|
||||||
## Langkah 4 - Tutup semua permintaan
|
## Langkah 4 - Tutup semua permintaan
|
||||||
Lokasi ([04](../../screenshots/04-location.png)), pemberitahuan
|
Lokasi ([04](../screenshots/04-location.png)), pemberitahuan
|
||||||
([05](../../screenshots/05-notifications.png)), kuki
|
([05](../screenshots/05-notifications.png)), kuki
|
||||||
([06](../../screenshots/06-cookies.png)).
|
([06](../screenshots/06-cookies.png)).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Apa yang kita pelajari:** tetingkap modal menghalang semua yang di
|
**Apa yang kita pelajari:** tetingkap modal menghalang semua yang di
|
||||||
belakangnya. Kita klik ALLOW, NOT INTERESTED dan I ACCEPT, dan langkau yang
|
belakangnya. Kita klik ALLOW, NOT INTERESTED dan I ACCEPT, dan langkau yang
|
||||||
tidak muncul (`TimeoutException` dikendalikan dan dilog).
|
tidak muncul (`TimeoutException` dikendalikan dan dilog).
|
||||||
|
|
||||||
## Langkah 5 - Tekan Like
|
## Langkah 5 - Tekan Like
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
**Apa yang kita pelajari:** pengecualian sebagai kawalan aliran untuk UI yang
|
**Apa yang kita pelajari:** pengecualian sebagai kawalan aliran untuk UI yang
|
||||||
tidak stabil: `NoSuchElementException` bermaksud "masih memuat, tunggu 2 saat
|
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
|
menghalang, klik BACK TO TINDER". Jeda antara "like" menjadikan bot kurang
|
||||||
ketara. Gelung berhenti pada had yang ditetapkan.
|
ketara. Gelung berhenti pada had yang ditetapkan.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Pemodenan berbanding penyelesaian terdahulu
|
## Pemodenan berbanding penyelesaian terdahulu
|
||||||
- Pakej `src/` dengan satu fungsi bagi setiap langkah dan bukannya satu kelas
|
- Pakej `src/` dengan satu fungsi bagi setiap langkah dan bukannya satu kelas
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
# Day 50 - Tinder auto find match (English)
|
# 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
|
Goal: automate logging in and liking profiles on TinDog with Python and
|
||||||
Selenium. Ethics first: tell your partner you automate, and respect the daily
|
Selenium. Ethics first: tell your partner you automate, and respect the daily
|
||||||
limit (TinDog 20, Tinder free tier 100).
|
limit (TinDog 20, Tinder free tier 100).
|
||||||
|
|
||||||
## Step 1 - Look at the site by hand
|
## Step 1 - Look at the site by hand
|
||||||

|

|
||||||
|
|
||||||
**What we gained:** before coding, click through manually and note which
|
**What we gained:** before coding, click through manually and note which
|
||||||
elements you must target. Good locators come from looking at the page first.
|
elements you must target. Good locators come from looking at the page first.
|
||||||
|
|
||||||
## Step 2 - Navigate to the login page
|
## Step 2 - Navigate to the login page
|
||||||

|

|
||||||
|
|
||||||
**What we gained:** `driver.get`, locating buttons with XPath
|
**What we gained:** `driver.get`, locating buttons with XPath
|
||||||
(`locators.py`) and waiting for them with `WebDriverWait` +
|
(`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.
|
`NoSuchElementException` on slow pages.
|
||||||
|
|
||||||
## Step 3 - The Facebook pop-up
|
## Step 3 - The Facebook pop-up
|
||||||

|

|
||||||
|
|
||||||
**What we gained:** the login opens a second browser window. We switch with
|
**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.
|
`driver.window_handles` and `switch_to.window`, fill the form, then switch back.
|
||||||
Credentials live in environment variables, never in code.
|
Credentials live in environment variables, never in code.
|
||||||
|
|
||||||
## Step 4 - Dismiss all requests
|
## Step 4 - Dismiss all requests
|
||||||
Location ([04](../../screenshots/04-location.png)), notifications
|
Location ([04](../screenshots/04-location.png)), notifications
|
||||||
([05](../../screenshots/05-notifications.png)), cookies
|
([05](../screenshots/05-notifications.png)), cookies
|
||||||
([06](../../screenshots/06-cookies.png)).
|
([06](../screenshots/06-cookies.png)).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**What we gained:** modal pop-ups block everything behind them. We click ALLOW,
|
**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
|
NOT INTERESTED and I ACCEPT, and skip a pop-up that does not appear
|
||||||
(`TimeoutException` is handled and logged).
|
(`TimeoutException` is handled and logged).
|
||||||
|
|
||||||
## Step 5 - Hit Like
|
## Step 5 - Hit Like
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
**What we gained:** exception handling as control flow for a flaky UI:
|
**What we gained:** exception handling as control flow for a flaky UI:
|
||||||
`NoSuchElementException` means "still loading, wait 2 s and retry";
|
`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.
|
BACK TO TINDER". A pause between likes keeps the bot from looking like a bot.
|
||||||
The loop stops at the configured limit.
|
The loop stops at the configured limit.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Modernisation compared with the earlier solution
|
## Modernisation compared with the earlier solution
|
||||||
- `src/` package with one function per step instead of one class with `sleep`.
|
- `src/` package with one function per step instead of one class with `sleep`.
|
||||||
Reference in New Issue
Block a user