Autor článku, jehož překlad dnes publikujeme, říká, že jeho cílem je vyprávět o vývoji webového scraperu v Pythonu s využitím Selenium, který provádí vyhledávání cen letenek. Při hledání letenek se používají flexibilní data (+- 3 dny kolem zadaných dat). Scraper ukládá výsledky vyhledávání do Excelového souboru a zasílá toho, kdo ho spustil, e-mail s obecnými informacemi o tom, co se mu podařilo najít. Cílem tohoto projektu je pomoci cestovatelům najít nejvýhodnější nabídky.
Pokud se při studiu materiálu cítíte ztraceni — podívejte se na článek.
Co budeme hledat?
Jste volní použít zde popisovaný systém jak chcete. Já ho například použil k hledání víkendových zájezdů a letenek do svého rodného města. Pokud to myslíte vážně s hledáním výhodných letenek — můžete spustit skript na serveru (jednoduchý , za 130 korun měsíčně, je na to naprosto vhodný) a nastavit ho tak, aby se spouštěl jednou nebo dvakrát denně. Výsledky vyhledávání vám budou přicházet e-mailem. Dále doporučuji vše nastavit tak, aby skript ukládal Excelový soubor s výsledky vyhledávání do složky Dropbox, což vám umožní prohlížet si podobné soubory odkudkoli a kdykoli.

Zatím jsem nenašel žádné chybné tarify, ale předpokládám, že to možné je
Při vyhledávání, jak již bylo zmíněno, se používají „flexibilní data“, skript nachází nabídky, které jsou v rámci tří dnů od zadaných dat. Ačkoliv při spuštění skriptu se hledání provádí pouze na jedno spojení, není obtížné jej upravit tak, aby mohl shromažďovat data o několika směrech letů. S jeho pomocí lze dokonce hledat chybné tarify, takové nálezy mohou být velmi zajímavé.
Proč potřebujeme další webový scraper?
Když jsem poprvé začal s web scrapingem, upřímně mě to moc nezajímalo. Chtěl jsem dělat více projektů v oblasti prediktivního modelování, finanční analýzy a možná v oblasti analýzy emocionálního zabarvení textů. Ale ukázalo se, že je to velmi zajímavé — ponořit se do toho, jak vytvořit program, který sbírá data z webových stránek. Jak jsem se tím více zabýval, pochopil jsem, že právě web scraping je 'motorem' internetu.
Možná si pomyslíte, že to je příliš odvážné tvrzení. Ale zamyslete se nad tím, že společnost Google začala s web scraperem, který Larry Page vytvořil pomocí Javy a Pythonu. Google roboti prozkoumávají a stále prozkoumávají internet, aby svým uživatelům poskytli nejlepší odpovědi na jejich otázky. Web scraping má nekonečné množství možností využití, a i když vás v oblasti Data Science zajímá něco jiného, budete potřebovat určité dovednosti scrappingu k získání dat pro analýzu.
Některé z technik zde použité jsem našel v úžasné o web scrapingu, kterou jsem nedávno získal. Obsahuje spoustu jednoduchých příkladů a nápadů na praktické využití toho, co jste se naučili. Navíc je tam velmi zajímavá kapitola o obcházení kontrol reCaptcha. Pro mě to byla novinka, protože jsem netušil, že existují specializované nástroje a dokonce celé služby pro řešení podobných úkolů.
Milujete cestování?!
Na jednoduchou a poměrně nezávadnou otázku, která je v nadpisu této části, často můžete slyšet kladnou odpověď doplněnou několika příběhy z cestování od toho, komu byla položena. Většina z nás souhlasí s tím, že cestování je skvělý způsob, jak se ponořit do nových kulturních prostředí a rozšířit si obzory. Nicméně pokud se někoho zeptáte, jestli ho baví hledat letenky, jsem si jistý, že odpověď bude už daleko méně pozitivní. Odborně vzato, tady nám na pomoc přichází Python.
Prvním úkolem, který musíme vyřešit na cestě k vytvoření systému pro vyhledávání informací o letenkách, je výběr vhodné platformy, ze které budeme čerpat informace. Řešení této úlohy se mi neukázalo jako snadné, ale nakonec jsem zvolil službu Kayak. Zkoušel jsem služby Momondo, Skyscanner, Expedia a ještě některé další, ale ochranné mechanismy proti robotům na těchto stránkách byly neprostupné. Po několika pokusech, kdy jsem se snažil přesvědčit systémy, že jsem člověk, musel jsem se potýkat se semafory, přechody pro chodce a bicykly. Rozhodl jsem se, že Kayak je pro mě nejvhodnější, přestože i zde, pokud během krátké doby načtete příliš mnoho stránek, začínají také kontroly. Podařilo se mi nastavit bota tak, aby posílal dotazy na stránky v intervalech 4 až 6 hodin, a všechno fungovalo v pořádku. Občas se vyskytnou obtíže také při práci s Kayak, ale pokud vás začnou obtěžovat kontroly, je potřeba je buď vyřešit ručně a poté spustit bota, nebo počkat několik hodin a kontroly by měly ustoupit. Pokud je to potřeba, můžete kód přizpůsobit pro jinou platformu a pokud to uděláte, můžete se o tom podělit v komentářích.
Pokud teprve začínáte se zveřejněním na webu a nevíte, proč se některé webové stránky snaží všemožně zabránit webovému skenování, předtím než začnete se svým prvním projektem v této oblasti, udělejte si laskavost a vyhledejte na Googlu materiály na téma „etiketa webového skenování“. Vaše experimenty se mohou ukončit dříve, než si myslíte, pokud se budete webovému skenování věnovat neopatrně.
Začínáme
Zde je obecný přehled toho, co se bude dít v kódu našeho webového skenovače:
- Import potřebných knihoven.
- Otevření karty v Google Chrome.
- Zavolání funkce, která spouští bota a předává mu města a data, která budou použita při hledání letenek.
- Tato funkce získává první výsledky vyhledávání seřazené podle kritéria největší atraktivity (best) a klikne na tlačítko pro načtení dalších výsledků.
- Další funkce shromažďuje data ze celé stránky a vrací data ve formátu rámce.
- Dva předchozí kroky se provádějí pomocí typů řazení podle ceny letenek (cheap) a podle rychlosti letu (fastest).
- Uživatel skriptu obdrží e-mail obsahující stručný přehled cen letenek (nejlevnější letenky a průměrná cena), a rámec dat s informacemi, seřazenými podle třech výše uvedených kritérií, je uložen ve formátu Excel.
- Všechny výše popsané akce se provádějí v cyklu během zadaného časového intervalu.
Je třeba poznamenat, že každý projekt Selenium začíná s webovým driverem. Používám , pracuji s Google Chrome, ale existují i další možnosti. Velké oblíbenosti se těší také PhantomJS a Firefox. Po stažení driveru je třeba jej umístit do příslušné složky, tím končí příprava na jeho použití. V prvních řádcích našeho skriptu se otevírá nová karta v Chrome.
Berme na vědomí, že ve svém vyprávění se nesnažím objevit nové horizonty hledání výhodných nabídek na letenky. Existují také mnohem pokročilejší techniky hledání podobných nabídek. Chci jen nabídnout čtenářům tohoto materiálu jednoduchý, ale prakticky použitelný způsob řešení tohoto úkolu.
Toto je kód, o kterém jsme hovořili výše.
from time import sleep, strftime
from random import randint
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import smtplib
from email.mime.multipart import MIMEMultipart
# Zde použijte svou cestu k chromedriveru!
chromedriver_path = 'C:/{YOUR PATH HERE}/chromedriver_win32/chromedriver.exe'
driver = webdriver.Chrome(executable_path=chromedriver_path) # Tímto příkazem se otevře okno Chrome
sleep(2) Na začátku kódu můžete vidět příkazy pro import balíčků, které se používají v celém našem projektu. Tak randint se používá k tomu, aby bot „ushnul“ na náhodný počet sekund, než začne novou operaci hledání. Obvykle se bez toho žádný bot neobejde. Pokud spustíte výše uvedený kód, otevře se okno Chrome, které bot použije k práci se webovými stránkami.
Provedeme malý experiment a otevřeme v novém okně stránku kayak.com. Vybereme město, ze kterého máme v plánu letět, a město, do kterého chceme přijet, stejně jako termíny letů. Při výběru termínů zkontrolujeme, aby byl použit interval +-3 dny. Napsal jsem kód s ohledem na to, co web vrací jako odpověď na podobné požadavky. Pokud například potřebujete hledat letenky pouze na zadané termíny, je velmi pravděpodobné, že budete muset kód bota upravit. Při vysvětlování kódu poskytuji odpovídající vysvětlení, ale pokud máte pocit, že jste se ztratili — dejte mi vědět.
Nyní klikneme na tlačítko pro spuštění hledání a podíváme se na odkaz v adresním řádku. Měl by vypadat podobně jako ten, který používám v příkladu níže, kde je deklarována proměnná kayak, která uchovává URL, a používá se metoda získat webového ovladače. Po kliknutí na tlačítko hledání by se na stránce měly objevit výsledky.
![]()
Když jsem použil příkaz získat více než dvě až tři krát během několika minut, nabídli mi projít kontrolou pomocí reCaptcha. Tuto kontrolu lze provést ručně a pokračovat v experimentování, dokud systém nedozrává k nové kontrole. Když jsem testoval skript, měl jsem pocit, že první vyhledávání vždy probíhá bez problémů, takže pokud chcete experimentovat s kódem, budete muset pouze občas ručně projít kontrolu a nechat kód běžet s dlouhými intervaly mezi vyhledáváními. A koneckonců, pokud o tom popřemýšlíte, člověku pravděpodobně nebudou potřebná data o cenách letenek získaná s 10minutovými intervaly mezi vyhledávacími operacemi.
Práce se stránkou pomocí XPath
Takže jsme otevřeli okno a načetli webovou stránku. Abychom získali informace o cenách a další údaje, musíme využít technologii XPath nebo CSS selektorů. Rozhodl jsem se zastavit na XPath a necítil jsem potřebu používat CSS selektory, ale rozhodně je možné pracovat i tak. Navigace po stránce pomocí XPath může být složitá a i když budete používat metody, které jsem popisoval v V článku, kde se používalo kopírování odpovídajících identifikátorů z kódu stránky, jsem si uvědomil, že to není optimální způsob, jak přistupovat k potřebným prvkům. Mimochodem, v kniha obsahuje vynikající popis základů práce se stránkami pomocí XPath a CSS selektorů. Takhle vypadá příslušná metoda webového ovladače.
![]()
Pokračujeme v práci na botovi. Využijeme možnosti programu pro výběr nejlevnějších letenek. Na následujícím obrázku je červeně zvýrazněn kód XPath selektoru. Abyste mohli prohlédnout kód, je potřeba kliknout pravým tlačítkem myši na zajímavý prvek stránky a v zobrazené nabídce zvolit možnost Zkontrolovat kód (Inspect). Tuto možnost lze vyvolat pro různé prvky stránky, jejichž kód se zobrazí a bude zvýrazněn v okně prohlížení kódu.

Prohlížení kódu stránky
Abych našel potvrzení svých úvah o nedostatcích kopírování selektorů z kódu, věnujte pozornost následujícím charakteristikám.
Co se stane při kopírování kódu:
//*[@id="wtKI-price_aTab"]/div[1]/div/div/div[1]/div/span/spanPro kopírování něčeho podobného je potřeba kliknout pravým tlačítkem myši na zajímavou část kódu a v zobrazené nabídce zvolit možnost Copy > Copy XPath.
Toto jsem použil pro určení tlačítka Cheapest:
cheap_results = ‘//a[@data-code = "price"]’ 
Příkaz Copy > Copy XPath
Je zřejmé, že druhá varianta vypadá mnohem jednodušeji. Při jejím použití se provádí hledání prvku a, který má atribut data-code, rovný price. Při použití první varianty se provádí hledání prvku, jehož hodnota je id wtKI-price_aTab , přičemž XPath cesta k prvku vypadá jako. Takový XPath dotaz na stránku si svou práci udělá, ale — jen jednou. Mohu vám teď říct, že /div[1]/div/div/div[1]/div/span/spanse změní při příštím načtení stránky. Řetězec id wtKI se dynamicky mění při každém načtení stránky, takže kód, ve kterém je použit, se po dalším znovu načtení stránky stane bezcenným. Proto si dejte nějaký čas na to, abyste se seznámili s XPath. Tyto znalosti vám budou prospěšné. Je však třeba poznamenat, že kopírování XPath selektorů může být užitečné při práci s poměrně jednoduchými weby, a pokud vám to vyhovuje, na tom není nic špatného.
Je třeba poznamenat, že kopírování XPath selektorů může být užitečné při práci s dostatečně jednoduchými weby, a pokud vám to vyhovuje, není na tom nic špatného.
Nyní si pověsme, co dělat, pokud potřebujeme získat všechny výsledky vyhledávání ve více řádcích uvnitř seznamu. Je to velmi jednoduché. Každý výsledek se nachází uvnitř objektu s třídou resultWrapper. Načtení všech výsledků může být provedeno v cyklu, který bude ukázán níže.
Je třeba poznamenat, že pokud vám je výše uvedené jasné, měli byste bez problémů pochopit většinu kódu, který budeme analyzovat. Během běhu tohoto kódu k tomu, co potřebujeme (ve skutečnosti je to prvek, do kterého je výsledek zabaleno), přistupujeme pomocí určitého mechanismu pro určení cesty (XPath). To se dělá proto, abychom získali text prvku a umístili ho do objektu, ze kterého lze údaje číst (nejprve se používá flight_containers, poté — flights_list).

Načítají se první tři řádky a jasně vidíme všechno, co potřebujeme. Máme však i zajímavější způsoby, jak získat informace. Musíme brát data z každého prvku jednotlivě.
Do práce!
Nejjednodušší je napsat funkci pro načtení dalších výsledků, takže začneme s ní. Chtěl bych maximalizovat počet letů, jejichž údaje program získá, a přitom nevzbudit podezření služby, která by vedla k kontrole, a proto každou stránku jednou stiskuji tlačítko Načíst další výsledky. V tomto kódu si dej pozor na blok catch (Exception), který jsem přidal, protože se někdy tlačítko nenačte správně. Pokud se s tím také setkáte — zakomentujte volání této funkce v kódu funkce start_kayak, kterou probereme níže.
# Загрузка большего количества результатов для того, чтобы максимизировать объём собираемых данных
def load_more():
try:
more_results = '//a[@class = "moreButton"]'
driver.find_element_by_xpath(more_results).click()
# Вывод этих заметок в ходе работы программы помогает мне быстро выяснить то, чем она занята
print('sleeping.....')
sleep(randint(45,60))
except:
passNyní, po dlouhém rozboru této funkce (někdy se mohu nechat unést), jsme připraveni oznámit funkci, která se postará o scrapping stránky.
Už jsem shromáždil většinu toho, co potřebuji, v následující funkci nazývané page_scrape. Někdy se vrácené údaje o etapách cesty ukáže jako sloučené, k jejich oddělení používám jednoduchou metodu. Například, když poprvé používám proměnné section_a_list a section_b_list. Naše funkce vrací datový rámec flights_df, to nám umožňuje oddělit výsledky získané při použití různých metod třídění dat a později je sloučit.
def page_scrape():
"""This function takes care of the scraping part"""
xp_sections = '//*[@class="section duration"]'
sections = driver.find_elements_by_xpath(xp_sections)
sections_list = [value.text for value in sections]
section_a_list = sections_list[::2] # так мы разделяем информацию о двух полётах
section_b_list = sections_list[1::2]
# Если вы наткнулись на reCaptcha, вам может понадобиться что-то предпринять.
# О том, что что-то пошло не так, вы узнаете исходя из того, что вышеприведённые списки пусты
# это выражение if позволяет завершить работу программы или сделать ещё что-нибудь
# тут можно приостановить работу, что позволит вам пройти проверку и продолжить скрапинг
# я использую тут SystemExit так как хочу протестировать всё с самого начала
if section_a_list == []:
raise SystemExit
# Я буду использовать букву A для уходящих рейсов и B для прибывающих
a_duration = []
a_section_names = []
for n in section_a_list:
# Получаем время
a_section_names.append(''.join(n.split()[2:5]))
a_duration.append(''.join(n.split()[0:2]))
b_duration = []
b_section_names = []
for n in section_b_list:
# Получаем время
b_section_names.append(''.join(n.split()[2:5]))
b_duration.append(''.join(n.split()[0:2]))
xp_dates = '//div[@class="section date"]'
dates = driver.find_elements_by_xpath(xp_dates)
dates_list = [value.text for value in dates]
a_date_list = dates_list[::2]
b_date_list = dates_list[1::2]
# Получаем день недели
a_day = [value.split()[0] for value in a_date_list]
a_weekday = [value.split()[1] for value in a_date_list]
b_day = [value.split()[0] for value in b_date_list]
b_weekday = [value.split()[1] for value in b_date_list]
# Получаем цены
xp_prices = '//a[@class="booking-link"]/span[@class="price option-text"]'
prices = driver.find_elements_by_xpath(xp_prices)
prices_list = [price.text.replace('$','') for price in prices if price.text != '']
prices_list = list(map(int, prices_list))
# stops - это большой список, в котором первый фрагмент пути находится по чётному индексу, а второй - по нечётному
xp_stops = '//div[@class="section stops"]/div[1]'
stops = driver.find_elements_by_xpath(xp_stops)
stops_list = [stop.text[0].replace('n','0') for stop in stops]
a_stop_list = stops_list[::2]
b_stop_list = stops_list[1::2]
xp_stops_cities = '//div[@class="section stops"]/div[2]'
stops_cities = driver.find_elements_by_xpath(xp_stops_cities)
stops_cities_list = [stop.text for stop in stops_cities]
a_stop_name_list = stops_cities_list[::2]
b_stop_name_list = stops_cities_list[1::2]
# сведения о компании-перевозчике, время отправления и прибытия для обоих рейсов
xp_schedule = '//div[@class="section times"]'
schedules = driver.find_elements_by_xpath(xp_schedule)
hours_list = []
carrier_list = []
for schedule in schedules:
hours_list.append(schedule.text.split('n')[0])
carrier_list.append(schedule.text.split('n')[1])
# разделяем сведения о времени и о перевозчиках между рейсами a и b
a_hours = hours_list[::2]
a_carrier = carrier_list[1::2]
b_hours = hours_list[::2]
b_carrier = carrier_list[1::2]
cols = (['Out Day', 'Out Time', 'Out Weekday', 'Out Airline', 'Out Cities', 'Out Duration', 'Out Stops', 'Out Stop Cities',
'Return Day', 'Return Time', 'Return Weekday', 'Return Airline', 'Return Cities', 'Return Duration', 'Return Stops', 'Return Stop Cities',
'Price'])
flights_df = pd.DataFrame({'Out Day': a_day,
'Out Weekday': a_weekday,
'Out Duration': a_duration,
'Out Cities': a_section_names,
'Return Day': b_day,
'Return Weekday': b_weekday,
'Return Duration': b_duration,
'Return Cities': b_section_names,
'Out Stops': a_stop_list,
'Out Stop Cities': a_stop_name_list,
'Return Stops': b_stop_list,
'Return Stop Cities': b_stop_name_list,
'Out Time': a_hours,
'Out Airline': a_carrier,
'Return Time': b_hours,
'Return Airline': b_carrier,
'Price': prices_list})[cols]
flights_df['timestamp'] = strftime("%Y%m%d-%H%M") # время сбора данных
return flights_df Snažil jsem se pojmenovat proměnné tak, aby byl kód srozumitelný. Pamatujte, že proměnné začínající na a se týkají první fáze cesty, zatímco b se týkají druhé. Přejdeme k další funkci.
Doplňkové mechanismy
Nyní máme funkci, která umožňuje načítat další výsledky vyhledávání a funkci pro zpracování těchto výsledků. Tímto článkem bychom mohli také skončit, protože tyto dvě funkce poskytují vše potřebné pro skenování stránek, které lze otevřít samostatně. Zatím jsme však neprobrali některé doplňkové mechanismy, o kterých jsme mluvili výše. Například je to kód pro odesílání e-mailů a další věci. To vše lze nalézt ve funkci start_kayak, kterou nyní prozkoumáme.
Pro fungování této funkce jsou potřebné informace o městech a datech. Tyto informace se používají k vytvoření odkazu v proměnné kayak, která se používá k přechodu na stránku, kde budou výsledky vyhledávání seřazeny podle nejlepší shody s dotazem. Po prvním skenování se budeme zabývat cenami, které se nacházejí v tabulce v horní části stránky. A to konkrétně tím, že najdeme minimální cenu jízdenky a průměrnou cenu. To vše, spolu s předpovědí, kterou web poskytne, bude odesláno e-mailem. Na stránce by měla být příslušná tabulka v levém horním rohu. Práce s touto tabulkou může mimochodem vyvolat chybu při vyhledávání pomocí přesných dat, protože v takovém případě se tabulka na stránce nezobrazuje.
def start_kayak(city_from, city_to, date_start, date_end):
"""Kódy měst - to jsou IATA kódy!
Formát data - YYYY-MM-DD"""
kayak = ('https://www.kayak.com/flights/' + city_from + '-' + city_to +
'/' + date_start + '-flexible/' + date_end + '-flexible?sort=bestflight_a')
driver.get(kayak)
sleep(randint(8,10))
# Někdy se objeví vyskakovací okno, pro kontrolu a jeho zavření lze použít blok try
try:
xp_popup_close = '//*[@contains(@id,"dialog-close") and contains(@class,"Button-No-Standard-Style close ")]'
driver.find_elements_by_xpath(xp_popup_close)[5].click()
except Exception as e:
pass
sleep(randint(60,95))
print('načítání více.....')
# load_more()
print('zahájení prvního scrapu.....')
df_flights_best = page_scrape()
df_flights_best['sort'] = 'best'
sleep(randint(60,80))
# Vezmeme nejnižší cenu z tabulky, která je umístěna v horní části stránky
matrix = driver.find_elements_by_xpath('/*[contains(@id,"FlexMatrixCell")]')
matrix_prices = [price.text.replace('$','') for price in matrix]
matrix_prices = list(map(int, matrix_prices))
matrix_min = min(matrix_prices)
matrix_avg = sum(matrix_prices)/len(matrix_prices)
print('přepínání na nejlevnější výsledky.....')
cheap_results = '//*[@data-code = "price"]'
driver.find_element_by_xpath(cheap_results).click()
sleep(randint(60,90))
print('načítání více.....')
# load_more()
print('zahájení druhého scrapu.....')
df_flights_cheap = page_scrape()
df_flights_cheap['sort'] = 'cheap'
sleep(randint(60,80))
print('přepínání na nejrychlejší výsledky.....')
quick_results = '//*[@data-code = "duration"]'
driver.find_element_by_xpath(quick_results).click()
sleep(randint(60,90))
print('načítání více.....')
# load_more()
print('zahájení třetího scrapu.....')
df_flights_fast = page_scrape()
df_flights_fast['sort'] = 'fast'
sleep(randint(60,80))
# Uložení nového rámce do Excel souboru, jehož název odráží města a data
final_df = df_flights_cheap.append(df_flights_best).append(df_flights_fast)
final_df.to_excel('search_backups//{}_flights_{}-{}_from_{}_to_{}.xlsx'.format(strftime("%Y%m%d-%H%M"),
city_from, city_to,
date_start, date_end), index=False)
print('ukládání df.....')
# Můžeme sledovat, jak se prognoza poskytovaná webem shoduje s realitou
xp_loading = '//*[@contains(@id,"advice")]'
loading = driver.find_element_by_xpath(xp_loading).text
xp_prediction = '//*[@class="info-text"]'
prediction = driver.find_element_by_xpath(xp_prediction).text
print(loading+'n'+prediction)
# Někdy se ve proměnné loading objeví tento řetězec, který později způsobuje problémy s odesíláním e-mailu
# pokud k tomu došlo - změníme ho na "Not Sure"
weird = '¯_(ツ)_/¯'
if loading == weird:
loading = 'Nejsem si jistý'
username = 'YOUREMAIL@hotmail.com'
password = 'VAŠE HESLO'
server = smtplib.SMTP('smtp.outlook.com', 587)
server.ehlo()
server.starttls()
server.login(username, password)
msg = ('Předmět: Flight Scrapernn
Nejlevnější let: {}nPrůměrná cena: {}nnDoporučení: {}nnKonec zprávy'.format(matrix_min, matrix_avg, (loading+'n'+prediction)))
message = MIMEMultipart()
message['From'] = 'YOUREMAIL@hotmail.com'
message['to'] = 'YOUROTHEREMAIL@domain.com'
server.sendmail('YOUREMAIL@hotmail.com', 'YOUROTHEREMAIL@domain.com', msg)
print('odesláno e-mail.....')Otestoval jsem tento skript s použitím účtu Outlook (hotmail.com). Nezkoušel jsem ho na správnost funkce s účtem Gmail, který je velmi populární, ale existuje spousta možných variant. Pokud používáte účet Hotmail, stačí vyplnit své údaje do kódu, aby to fungovalo.
Pokud chcete pochopit, co se přesně vykonává v jednotlivých částech kódu této funkce, můžete je zkopírovat a experimentovat s nimi. Experimentování s kódem je jediný způsob, jak ho pořádně pochopit.
Hotový systém
Teď, když je všechno uděláno, o čem jsme mluvili, můžeme vytvořit jednoduchou smyčku, ve které voláme naše funkce. Skript žádá od uživatele údaje o městech a datech. Při testování s trvalým restartováním skriptu si pravděpodobně nebudete chtít pokaždé zadávat tyto informace ručně, proto lze příslušné řetězce během testování zakomentovat a odkomentovat ty, které následují níže, ve kterých jsou tvrdě nastaveny potřebné údaje pro skript.
city_from = input('Z kterého města? ')
city_to = input('Kam? ')
date_start = input('Hledat kolem kterého data odletu? Prosím použijte pouze formát RRRR-MM-DD ')
date_end = input('Kdy se vrátit? Prosím použijte pouze formát RRRR-MM-DD ')
# city_from = 'LIS'
# city_to = 'SIN'
# date_start = '2019-08-21'
# date_end = '2019-09-07'
for n in range(0,5):
start_kayak(city_from, city_to, date_start, date_end)
print('iterace {} byla dokončena @ {}'.format(n, strftime("%Y%m%d-%H%M")))
# Čekáme 4 hodiny
sleep(60*60*4)
print('čekání skončeno.....') Takto vypadá testovací spuštění skriptu.

Testovací spuštění skriptu
Závěry
Pokud jste se dostali do tohoto bodu — gratuluji! Nyní máte funkční webový scraper, i když již vidím spoustu možností jeho zlepšení. Například je možné jej integrovat s Twilio, aby místo e-mailů posílal textové zprávy. Můžete použít VPN nebo něco jiného, abyste současně získali výsledky z několika serverů. Existuje také občasně vznikající problém s ověřováním uživatele webu, zda je skutečnou osobou, ale i tento problém lze vyřešit. V každém případě nyní máte základ, který můžete podle potřeby rozšiřovat. Například tak, aby byl soubor Excel uživateli zasílán jako příloha e-mailu.
Pouze registrovaní uživatelé se mohou účastnit ankety. , prosím.
Používáte technologie web scraping?
Ano
Ne
Hlasovalo 8 uživatelů. Zdržel se 1 uživatel.
Zdroj: habr.com
