Python est un assistant pour trouver des vols pas chers pour ceux qui aiment voyager

L'auteur de l'article, dont nous publions la traduction aujourd'hui, dit que son objectif est de parler du développement d'un grattoir Web en Python à l'aide de Selenium, qui recherche les prix des billets d'avion. Lors de la recherche de billets, des dates flexibles sont utilisées (+ - 3 jours par rapport aux dates spécifiées). Scraper enregistre les résultats de la recherche dans un fichier Excel et envoie à la personne qui l'a lancé un e-mail contenant des informations générales sur ce qu'il a réussi à trouver. L'objectif de ce projet est d'aider les voyageurs à trouver les meilleures offres.



Si vous, lorsque vous traitez le matériel, vous sentez perdu - jetez un œil à cet article.

Que recherchons-nous?


Vous êtes libre d'utiliser le système décrit ici comme vous le souhaitez. Par exemple, je l'ai utilisé pour rechercher des visites de week-end et des billets pour ma ville natale. Si vous cherchez sérieusement à trouver des billets rentables, vous pouvez exécuter le script sur le serveur (un simple serveur , pour 130 roubles par mois, convient tout à fait) et le faire fonctionner une ou deux fois par jour. Les résultats de la recherche vous seront envoyés par e-mail. De plus, je vous recommande de tout configurer pour que le script enregistre le fichier Excel avec les résultats de la recherche dans le dossier Dropbox, ce qui vous permet de visualiser ces fichiers de n'importe où et à tout moment.


Je n'ai pas encore trouvé de tarifs avec des erreurs, mais je pense que c'est possible

Lors de la recherche, comme cela a déjà été dit, une «date flexible» est utilisée, le script trouve des offres dans les trois jours à partir des dates données. Bien qu'au démarrage du script, il recherche des offres dans une seule direction, il est facile de l'affiner pour qu'il puisse collecter des données dans plusieurs directions de vols. Avec son aide, vous pouvez même rechercher des tarifs erronés, de telles trouvailles peuvent être très intéressantes.

Pourquoi ai-je besoin d'un autre grattoir Web?


Quand j'ai commencé à gratter le Web, pour être honnête, ce n'était pas particulièrement intéressant. Je voulais faire plus de projets dans le domaine de la modélisation prédictive, de l'analyse financière, et, éventuellement, dans le domaine de l'analyse de la coloration émotionnelle des textes. Mais il s'est avéré que c'était très intéressant - de comprendre comment créer un programme qui collecte des données à partir de sites Web. En approfondissant ce sujet, je me suis rendu compte que le Web scraping est le «moteur» d'Internet.

Vous pouvez décider que cette déclaration est trop audacieuse. Mais pensez à la façon dont Google a commencé avec un grattoir Web créé par Larry Page en utilisant Java et Python. Googlebots a recherché et exploré Internet, essayant de fournir à ses utilisateurs les meilleures réponses possibles à leurs questions. Le scraping Web a un nombre infini d'applications, et même si vous, dans le domaine de la science des données, êtes intéressé par autre chose, alors pour acquérir des données à analyser, vous aurez besoin de quelques compétences en scraping.

J'ai trouvé quelques astuces utilisées ici dans un merveilleux livre sur le web scraping, que j'ai récemment acquis. Vous y trouverez de nombreux exemples et idées simples sur l'application pratique des études. De plus, il y a un chapitre très intéressant sur le bypass de test reCaptcha. Pour moi, c'était une nouvelle, car je ne savais pas qu'il y avait des outils spéciaux et même des services entiers pour résoudre de tels problèmes.

Aimez-vous voyager?!


À la question simple et plutôt inoffensive posée dans le titre de cette section, on peut souvent entendre une réponse positive, accompagnée de quelques récits de voyage de la personne à qui il a été posé. La plupart d'entre nous conviendront que voyager est un excellent moyen de plonger dans de nouveaux environnements culturels et d'élargir nos horizons. Cependant, si vous posez à quelqu'un une question à savoir s'il aime chercher des billets d'avion, je suis sûr que la réponse sera loin d'être aussi positive. En fait, ici Python vient à la rescousse.

La première tâche que nous devons résoudre sur la manière de créer un système de recherche d'informations sur les billets d'avion sera la sélection d'une plate-forme appropriée avec laquelle nous prendrons des informations. La solution à ce problème n'a pas été facile pour moi, mais j'ai finalement choisi le service Kayak. J'ai essayé les services de Momondo, Skyscanner, Expedia, et quelques autres, mais les mécanismes de protection contre les robots sur ces ressources étaient impénétrables. Après plusieurs tentatives, au cours desquelles, en essayant de convaincre les systèmes que j'étais humain, j'ai dû faire face à des feux de signalisation, des passages pour piétons et des vélos, j'ai décidé que le kayak me convenait le mieux, même si ici aussi, si charger trop de pages en peu de temps, les vérifications commencent également. J'ai réussi à faire envoyer des requêtes au bot sur le site à des intervalles de 4 à 6 heures, et tout a bien fonctionné. Des difficultés surviennent de temps en temps lorsque vous travaillez avec Kayak, mais si vous commencez à être gêné par les contrôles, vous devez alors les traiter manuellement, puis démarrer le bot, ou attendre quelques heures, et les contrôles devraient s'arrêter. Si nécessaire, vous pouvez bien adapter le code pour une autre plate-forme, et si vous le faites, vous pouvez le signaler dans les commentaires.

Si vous débutez avec le Web scraping et que vous ne savez pas pourquoi certains sites Web ont du mal à le faire, alors avant de commencer votre premier projet dans ce domaine, faites-vous plaisir et recherchez des mots sur Google. "Étiquette de raclage Web". Vos expériences peuvent se terminer plus tôt que vous ne le pensez si vous êtes indûment engagé dans le scraping Web.

Pour commencer


Voici un aperçu général de ce qui se passera dans le code de notre grattoir Web:

  • Importez les bibliothèques requises.
  • Ouvrez l'onglet Google Chrome.
  • Appel de la fonction qui lance le bot, en lui passant la ville et la date qui seront utilisées lors de la recherche de billets.
  • Cette fonction reçoit les premiers résultats de recherche, triés selon les critères les plus attractifs (les meilleurs), et appuie sur le bouton pour charger des résultats supplémentaires.
  • Une autre fonction collecte les données de la page entière et renvoie un bloc de données.
  • Les deux étapes précédentes sont effectuées en utilisant des types de tri par prix du billet (bon marché) et par vitesse de vol (le plus rapide).
  • Un e-mail est envoyé à l'utilisateur du script contenant un bref résumé des prix des billets (billets les moins chers et prix moyen), et une trame de données avec des informations triées par les trois indicateurs susmentionnés est enregistrée dans un fichier Excel.
  • Toutes les actions ci-dessus sont effectuées dans un cycle après une période de temps spécifiée.

Il convient de noter que chaque projet Selenium commence par un pilote Web. J'utilise Chromedriver , je travaille avec Google Chrome, mais il existe d'autres options. PhantomJS et Firefox sont également populaires. Après avoir chargé le pilote, vous devez le placer dans le dossier approprié, ceci termine la préparation de son utilisation. Les premières lignes de notre script ouvrent un nouvel onglet Chrome.

Gardez à l'esprit que, dans mon histoire, je n'essaie pas d'ouvrir de nouveaux horizons pour trouver des offres rentables sur les billets d'avion. Il existe des techniques beaucoup plus avancées pour trouver de telles offres. Je veux juste offrir aux lecteurs de ce matériel un moyen simple mais pratique de résoudre ce problème.

Voici le code dont nous avons parlé ci-dessus.

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 #      chromedriver! chromedriver_path = 'C:/{YOUR PATH HERE}/chromedriver_win32/chromedriver.exe' driver = webdriver.Chrome(executable_path=chromedriver_path) #     Chrome sleep(2) 

Au début du code, vous pouvez voir les commandes d'importation de packages utilisées tout au long de notre projet. Ainsi, randint est utilisé pour que le bot "s'endorme" pendant un nombre aléatoire de secondes avant de démarrer une nouvelle opération de recherche. Habituellement, aucun robot ne peut s'en passer. Si vous exécutez le code ci-dessus, une fenêtre Chrome s'ouvrira, que le bot utilisera pour travailler avec des sites.

Faisons une petite expérience et ouvrons le site kayak.com dans une fenêtre séparée. Choisissez la ville à partir de laquelle nous allons voler, la ville vers laquelle vous souhaitez vous rendre ainsi que les dates des vols. Lors du choix des dates, nous vérifierons que la plage est de + -3 jours. J'ai écrit le code en tenant compte de ce que le site produit en réponse à de telles demandes. Si, par exemple, vous devez rechercher des billets uniquement à des dates données, il est fort probable que vous deviez modifier le code du bot. En parlant du code, je fais des explications appropriées, mais si vous sentez que vous êtes confus - faites le moi savoir.

Maintenant, cliquez sur le bouton de démarrage de la recherche et regardez le lien dans la barre d'adresse. Il devrait ressembler au lien que j'utilise dans l'exemple ci-dessous, où la variable kayak qui stocke l'URL est déclarée et la méthode get du pilote Web est utilisée. Après avoir cliqué sur le bouton de recherche, les résultats devraient apparaître sur la page.


Lorsque j'ai utilisé la commande get plus de deux à trois fois en quelques minutes, on m'a demandé de passer un test à l'aide de reCaptcha. Vous pouvez effectuer cette vérification manuellement et poursuivre les expériences jusqu'à ce que le système décide d'organiser une nouvelle vérification. Lorsque j'ai testé le script, j'avais l'impression que la première session de recherche se passait toujours sans problème, donc si vous voulez expérimenter avec le code, il vous suffit de le vérifier périodiquement manuellement et de laisser le code être exécuté en utilisant de longs intervalles entre les sessions de recherche. Oui, et si vous y réfléchissez, il est peu probable qu'une personne ait besoin d'informations sur les prix des billets reçus à des intervalles de 10 minutes entre les opérations de recherche.

Utilisation d'une page à l'aide de XPath


Nous avons donc ouvert la fenêtre et chargé le site. Pour obtenir les prix et d'autres informations, nous devons utiliser la technologie XPath ou des sélecteurs CSS. J'ai décidé de m'attarder sur XPath et je n'ai pas ressenti le besoin d'utiliser des sélecteurs CSS, mais il est tout à fait possible de travailler comme ça. Se déplacer dans une page à l'aide de XPath peut être une tâche intimidante, et même si vous utilisez les méthodes que j'ai décrites dans cet article, qui ont utilisé la copie des identifiants correspondants à partir du code de la page, j'ai réalisé que ce n'était en fait pas le meilleur moyen d'accéder éléments nécessaires. À propos, dans ce livre, vous pouvez trouver une excellente description des bases de l'utilisation des pages à l'aide des sélecteurs XPath et CSS. Voici à quoi ressemble la méthode du pilote Web correspondante.


Nous continuons donc à travailler sur le bot. Profitez du programme pour sélectionner les billets les moins chers. Dans l'image suivante, le code de sélection XPath est surligné en rouge. Pour afficher le code, vous devez cliquer avec le bouton droit sur l'élément de la page qui vous intéresse et sélectionner la commande Inspecter dans le menu qui apparaît. Cette commande peut être appelée pour différents éléments de page, dont le code sera affiché et mis en évidence dans la fenêtre d'affichage du code.


Afficher le code de page

Afin de trouver la confirmation de mon raisonnement sur les inconvénients de copier des sélecteurs à partir du code, faites attention aux fonctionnalités suivantes.

Voici ce que vous obtenez en copiant du code:

 //*[@id="wtKI-price_aTab"]/div[1]/div/div/div[1]/div/span/span 

Pour copier quelque chose de similaire, vous devez cliquer avec le bouton droit sur la partie du code qui vous intéresse et sélectionner Copier> Copier XPath dans le menu qui apparaît.

Voici ce que j'ai utilisé pour définir le bouton le moins cher:

 cheap_results = '//a[@data-code = "price"]' 


Copier> Copier la commande XPath

Il est assez évident que la deuxième option semble beaucoup plus simple. Lorsqu'il l'utilise, il recherche l'élément a, dont l'attribut data-code égal à price . En utilisant la première option, un élément id est recherché, qui est wtKI-price_aTab , et le chemin XPath vers l'élément ressemble à /div[1]/div/div/div[1]/div/span/span . Une requête XPath similaire à une page fera l'affaire, mais une seule fois. Je peux dire maintenant que l' id changera la prochaine fois que la page se chargera. La wtKI caractères wtKI change dynamiquement chaque fois que la page est chargée, par conséquent, le code dans lequel elle est utilisée sera inutile après le rechargement de la page suivante. Prenez donc le temps de comprendre XPath. Cette connaissance vous sera utile.

Cependant, il convient de noter que la copie des sélecteurs XPath peut être utile lorsque vous travaillez avec des sites assez simples, et si cela vous convient, il n'y a rien de mal à cela.

Maintenant, réfléchissons à quoi faire si vous avez besoin d'obtenir tous les résultats de la recherche sur plusieurs lignes, à l'intérieur de la liste. Très simple. Chaque résultat se trouve dans un objet avec la classe resultWrapper . Le téléchargement de tous les résultats peut être effectué dans une boucle qui ressemble à celle illustrée ci-dessous.

Il convient de noter que si vous comprenez ce qui précède, vous devez facilement comprendre la plupart du code que nous analyserons. Au cours du travail de ce code, nous nous tournons vers ce dont nous avons besoin (en fait, c'est l'élément dans lequel le résultat est encapsulé) en utilisant un mécanisme pour indiquer le chemin (XPath). Ceci est fait afin d'obtenir le texte de l'élément et de le placer dans un objet à partir duquel les données peuvent être lues (utilisez d'abord flight_containers , puis flights_list ).


Les trois premières lignes sont affichées et nous pouvons voir clairement tout ce dont nous avons besoin. Cependant, nous avons des moyens plus intéressants d'obtenir des informations. Nous devons prendre les données de chaque élément séparément.

Pour travailler!


Il est plus facile d'écrire une fonction pour charger des résultats supplémentaires, alors commençons par elle. Je souhaite maximiser le nombre de vols pour lesquels le programme reçoit des informations et, en même temps, ne pas provoquer de suspicions dans le service menant à une vérification.Je clique donc sur le bouton Charger plus de résultats une fois à chaque fois que la page est affichée. Dans ce code, vous devez faire attention au bloc try , que j'ai ajouté en raison du fait que parfois le bouton ne se charge pas normalement. Si vous rencontrez également cela, commentez les appels à cette fonction dans le code de la fonction start_kayak , dont nous parlerons ci-dessous.

 #      ,      def load_more():   try:       more_results = '//a[@class = "moreButton"]'       driver.find_element_by_xpath(more_results).click()       #            ,          print('sleeping.....')       sleep(randint(45,60))   except:       pass 

Maintenant, après une longue analyse de cette fonction (parfois je peux m'emballer), nous sommes prêts à déclarer une fonction qui traitera du scrap de page.

J'ai déjà rassemblé la plupart de ce qui est nécessaire dans la prochaine fonction appelée page_scrape . Parfois, les données renvoyées sur les étapes du chemin s'avèrent être combinées, pour leur séparation, j'utilise une méthode simple. Par exemple, la première fois que j'utilise les variables section_a_list et section_b_list . Notre fonction renvoie la trame de données flights_df , ce qui nous permet de séparer les résultats obtenus en utilisant différentes méthodes de tri des données, puis de les combiner.

 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 

J'ai essayé de nommer les variables pour que le code soit clair. N'oubliez pas que les variables commençant par a font référence à la première étape du chemin et b à la seconde. Passez à la fonction suivante.

Mécanismes auxiliaires


Nous avons maintenant une fonction qui vous permet de charger des résultats de recherche supplémentaires et une fonction pour traiter ces résultats. Cet article pourrait être complété à ce sujet, car ces deux fonctions fournissent tout le nécessaire pour supprimer des pages pouvant être ouvertes indépendamment. Mais nous n'avons pas encore examiné certains des mécanismes auxiliaires discutés ci-dessus. Par exemple, il s'agit du code pour envoyer des e-mails et d'autres choses. Tout cela peut être trouvé dans la fonction start_kayak , que nous considérons maintenant.

Pour utiliser cette fonction, vous avez besoin d'informations sur les villes et les dates. À l'aide de ces informations, elle forme un lien dans la variable kayak , qui est utilisée pour accéder à une page qui contiendra les résultats de la recherche triés par leur meilleure correspondance. Après la première session de grattage, nous travaillerons avec les prix dans le tableau en haut de la page. A savoir, nous trouvons le prix minimum du billet et le prix moyen. Tout cela, ainsi que la prédiction émise par le site, seront envoyés par e-mail. Sur la page, le tableau correspondant doit être dans le coin supérieur gauche. Soit dit en passant, travailler avec ce tableau peut provoquer une erreur lors de la recherche en utilisant des dates exactes, car dans ce cas, le tableau n'est pas affiché sur la page.

 def start_kayak(city_from, city_to, date_start, date_end):   """City codes - it's the IATA codes!   Date format -  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))     #    ,           try   try:       xp_popup_close = '//button[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('loading more.....')  #     load_more()     print('starting first scrape.....')   df_flights_best = page_scrape()   df_flights_best['sort'] = 'best'   sleep(randint(60,80))     #      ,        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('switching to cheapest results.....')   cheap_results = '//a[@data-code = "price"]'   driver.find_element_by_xpath(cheap_results).click()   sleep(randint(60,90))   print('loading more.....')  #     load_more()     print('starting second scrape.....')   df_flights_cheap = page_scrape()   df_flights_cheap['sort'] = 'cheap'   sleep(randint(60,80))     print('switching to quickest results.....')   quick_results = '//a[@data-code = "duration"]'   driver.find_element_by_xpath(quick_results).click()    sleep(randint(60,90))   print('loading more.....')  #     load_more()     print('starting third scrape.....')   df_flights_fast = page_scrape()   df_flights_fast['sort'] = 'fast'   sleep(randint(60,80))     #     Excel-,         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('saved df.....')     #    ,  ,  ,      xp_loading = '//div[contains(@id,"advice")]'   loading = driver.find_element_by_xpath(xp_loading).text   xp_prediction = '//span[@class="info-text"]'   prediction = driver.find_element_by_xpath(xp_prediction).text   print(loading+'\n'+prediction)     #    loading   , , ,        #    -    "Not Sure"   weird = '¯\\_(ツ)_/¯'   if loading == weird:       loading = 'Not sure'     username = 'YOUREMAIL@hotmail.com'   password = 'YOUR PASSWORD'   server = smtplib.SMTP('smtp.outlook.com', 587)   server.ehlo()   server.starttls()   server.login(username, password)   msg = ('Subject: Flight Scraper\n\n\ Cheapest Flight: {}\nAverage Price: {}\n\nRecommendation: {}\n\nEnd of message'.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('sent email.....') 

J'ai testé ce script en utilisant un compte Outlook (hotmail.com). Je ne l'ai pas vérifié pour le bon fonctionnement du compte Gmail, ce système de messagerie est très populaire, mais il existe de nombreuses options possibles. Si vous utilisez un compte Hotmail, pour que tout fonctionne, il vous suffit de saisir vos données dans le code.

Si vous voulez comprendre exactement ce qui est effectué dans des sections distinctes du code de cette fonction, vous pouvez les copier et les expérimenter. Les expériences de code sont le seul moyen de le comprendre.

Système prêt


Maintenant que tout ce dont nous avons parlé est terminé, nous pouvons créer une boucle simple dans laquelle nos fonctions sont appelées. Le script demande à l'utilisateur des données sur les villes et les dates. Lorsque vous testez avec un redémarrage constant du script, il est peu probable que vous souhaitiez entrer ces données manuellement à chaque fois, de sorte que les lignes correspondantes, pendant la durée du test, peuvent être mises en commentaire en décommentant celles en dessous dans lesquelles les données nécessaires au script sont codées en dur.

 city_from = input('From which city? ') city_to = input('Where to? ') date_start = input('Search around which departure date? Please use YYYY-MM-DD format only ') date_end = input('Return when? Please use YYYY-MM-DD format only ') # 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('iteration {} was complete @ {}'.format(n, strftime("%Y%m%d-%H%M")))     #  4    sleep(60*60*4)   print('sleep finished.....') 

Voici le test du script.

Script d'exécution de test

Résumé


Si vous arrivez à ce point - félicitations! Vous avez maintenant un grattoir Web fonctionnel, même si je vois déjà de nombreuses façons de l'améliorer. Par exemple, il peut être intégré à Twilio afin que, au lieu des e-mails, il envoie des messages texte. Vous pouvez utiliser un VPN ou autre chose pour recevoir simultanément les résultats de plusieurs serveurs. Il y a également un problème récurrent avec la vérification de l'utilisateur du site pour savoir s'il est une personne, mais ce problème peut également être résolu. Dans tous les cas, vous avez maintenant une base que vous pouvez agrandir si vous le souhaitez. Par exemple, pour vous assurer que le fichier Excel est envoyé à l'utilisateur en tant que pièce jointe à un e-mail.

Source: https://habr.com/ru/post/fr451872/


All Articles