W pracy programisty i analityka danych bardzo często pojawia się potrzeba cyklicznego uruchamiania skryptu: od pobierania notowań giełdowych co kilka minut, po nocne sprzątanie logów z poprzedniego dnia.
Ręczne odpalanie skryptu za każdym razem nie ma sensu. Na potrzeby lokalnych zastosowań można oprzeć się na dwóch
praktycznych podejściach: wewnętrznej pętli w samym programie (np. z użyciem biblioteki
schedule) lub powierzeniu zadania systemowi operacyjnemu (np. Harmonogram zadań w Windows).
W tym wpisie omawiam obie metody oraz typowe problemy przy ich konfiguracji.
I. Aplikacyjny scheduler w Pythonie (biblioteka schedule)
To podejście sprawdza się, gdy skrypt ma działać ciągle i wykonywać zadanie dość często (np. co 3–5 minut). Typowe przykłady to ciągły crawler lub lekki serwis monitorujący dane.
1. Instalacja i podstawowa konfiguracja
Najpierw instalujemy bibliotekę schedule:
pip install schedule
2. Szkielet kodu
W schedule definiujemy funkcję–zadanie, konfigurujemy regułę harmonogramu
i utrzymujemy prostą pętlę, która co chwilę sprawdza, czy coś ma się wykonać:
import schedule
import time
from datetime import datetime
def fetch_data_task():
"""Przykładowe zadanie cykliczne."""
try:
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Przy pracy w tle nie zakładaj, że zobaczysz output w terminalu – loguj do pliku.
with open("task_log.txt", "a", encoding="utf-8") as f:
f.write(f"[{current_time}] Zadanie wykonane poprawnie\n")
except Exception as e:
with open("task_log.txt", "a", encoding="utf-8") as f:
f.write(f"Zadanie zakończone błędem: {e}\n")
# przykład: uruchom zadanie co 2 minuty
schedule.every(2).minutes.do(fetch_data_task)
# alternatywnie: schedule.every().day.at("08:30").do(fetch_data_task)
if __name__ == "__main__":
while True:
schedule.run_pending()
time.sleep(1) # ważne: nie zajeżdżaj CPU pustą pętlą
Linia time.sleep(1) jest kluczowa – bez niej nieskończona pętla będzie pędziła
na 100% jednego rdzenia CPU.
II. Harmonogram zadań Windows (warstwa systemu)
Gdy zadanie ma uruchamiać się np. raz dziennie o konkretnej godzinie lub po starcie systemu, a Ty nie chcesz mieć otwartego okna konsoli, lepiej oddać harmonogram w ręce systemu (Task Scheduler).
1. Sprawdzenie ścieżki do Pythona
Najczęstszy powód porażek w Harmonogramie to brak prawidłowego PATH.
W wierszu poleceń sprawdź:
where python
Jeśli zobaczysz pełną ścieżkę (np. C:\Python310\python.exe), skopiuj ją –
przyda się za chwilę. Jeśli polecenie nie zwraca nic, trzeba dodać katalog z
python.exe do zmiennej środowiskowej Path w ustawieniach systemu.
2. Tworzenie zadania w Harmonogramie
W skrócie proces wygląda tak:
- Uruchom"Harmonogram zadań” (Task Scheduler) z menu Start.
- Wybierz"Utwórz zadanie podstawowe…”.
- Jako wyzwalacz ustaw np."Codziennie” lub"Po uruchomieniu komputera”.
- Jako akcję wybierz"Uruchom program”.
- W polu"Program/skrypt” wklej pełną ścieżkę do
python.exe. - W"Dodaj argumenty” wpisz pełną ścieżkę do skryptu, np.
D:\scripts\my_task.py.
3. Ustawienia zwiększające niezawodność
Po utworzeniu zadania wejdź w jego"Właściwości” i:
- Na karcie Ogólne zaznacz"Uruchom niezależnie od tego, czy użytkownik jest zalogowany, czy nie”.
- Na karcie Ustawienia zaznacz opcję typu"Uruchom zadanie jak najszybciej po pominięciu zaplanowanego czasu” – pomoże przy restartach/awariach.
III. Typowe problemy i jak do nich podejść
-
Brak śladu działania – jeśli skrypt działa w tle, nie polegaj na
print(). Zapisuj logi do pliku (tak jak w przykładzie ztask_log.txt), inaczej nawet poprawne wykonanie będzie"niewidoczne”. -
Okno konsoli pojawia się i znika (tzw. flash) – zwykle oznacza nieobsłużony wyjątek.
Pomaga globalny
try/exceptz logowaniem błędu, ewentualnie na końcu skryptu krótkietime.sleep(5), żeby zdążyć przeczytać komunikat. -
Brak modułów / zła wersja Pythona – jeśli masz kilka instalacji Pythona,
where pythonmoże wskazywać inną ścieżkę niż ta, której używasz w IDE. Biblioteki zainstalowane w jednym środowisku nie będą widoczne w drugim.
IV. Trzy punkty kontrolne na koniec
-
Kontrola pętli nieskończonej – przy podejściu z
schedulezawsze dodawajtime.sleep(1)albo większą wartość, żeby nie obciążać niepotrzebnie CPU. - Logi zamiast konsoli – zadania działające w tle zawsze powinny pisać do pliku tekstowego / logów, nie tylko na standardowe wyjście.
- Używaj ścieżek absolutnych – zarówno w Harmonogramie zadań, jak i w samym skrypcie staraj się podawać pełne ścieżki (z literą dysku), unikaj spacji i nietypowych znaków w nazwach katalogów, żeby nie dokładać sobie problemów z parsowaniem ścieżek.