पायथन - ज्यांना प्रवास करायला आवडते त्यांच्यासाठी स्वस्त हवाई तिकिटे शोधण्यात सहाय्यक

लेखाचे लेखक, ज्याचे भाषांतर आम्ही आज प्रकाशित करत आहोत, असे म्हणतात की सेलेनियमचा वापर करून पायथनमध्ये वेब स्क्रॅपरच्या विकासाबद्दल बोलणे हे त्याचे उद्दिष्ट आहे, जे विमान तिकिटांच्या किंमती शोधते. तिकिटे शोधताना, लवचिक तारखा वापरल्या जातात (निर्दिष्ट तारखांच्या तुलनेत +- 3 दिवस). स्क्रॅपर एक्सेल फाईलमध्ये शोध परिणाम जतन करतो आणि ज्याने शोध घेतला त्या व्यक्तीला त्यांना काय सापडले याचा सारांश ईमेल पाठवते. प्रवाशांना सर्वोत्तम डील शोधण्यात मदत करणे हे या प्रकल्पाचे उद्दिष्ट आहे.

पायथन - ज्यांना प्रवास करायला आवडते त्यांच्यासाठी स्वस्त हवाई तिकिटे शोधण्यात सहाय्यक

जर, सामग्री समजून घेताना, तुम्हाला हरवल्यासारखे वाटत असेल, तर एक नजर टाका हे लेख.

आपण काय शोधणार आहोत?

तुम्ही तुमच्या इच्छेनुसार येथे वर्णन केलेली प्रणाली वापरण्यास मोकळे आहात. उदाहरणार्थ, मी ते माझ्या गावी वीकेंड टूर आणि तिकिटे शोधण्यासाठी वापरले. तुम्ही फायदेशीर तिकिटे शोधण्याबाबत गंभीर असल्यास, तुम्ही सर्व्हरवर स्क्रिप्ट चालवू शकता (साधे सर्व्हर, महिन्याला 130 रूबलसाठी, यासाठी योग्य आहे) आणि ते दिवसातून एकदा किंवा दोनदा चालते याची खात्री करा. शोध परिणाम तुम्हाला ईमेलद्वारे पाठवले जातील. याव्यतिरिक्त, मी सर्वकाही सेट करण्याची शिफारस करतो जेणेकरून स्क्रिप्ट ड्रॉपबॉक्स फोल्डरमध्ये शोध परिणामांसह एक्सेल फाइल जतन करेल, ज्यामुळे तुम्हाला अशा फाइल्स कोठूनही आणि कोणत्याही वेळी पाहण्याची परवानगी मिळेल.

पायथन - ज्यांना प्रवास करायला आवडते त्यांच्यासाठी स्वस्त हवाई तिकिटे शोधण्यात सहाय्यक
मला अद्याप त्रुटी असलेले दर आढळले नाहीत, परंतु मला वाटते की ते शक्य आहे

शोधताना, आधीच नमूद केल्याप्रमाणे, "लवचिक तारीख" वापरली जाते; स्क्रिप्ट दिलेल्या तारखांच्या तीन दिवसांच्या आत ऑफर शोधते. जरी स्क्रिप्ट चालवताना, ते फक्त एकाच दिशेने ऑफर शोधते, ते सुधारणे सोपे आहे जेणेकरून ते अनेक उड्डाण दिशानिर्देशांवर डेटा संकलित करू शकेल. त्याच्या मदतीने, आपण चुकीचे दर देखील शोधू शकता; असे शोध खूप मनोरंजक असू शकतात.

तुम्हाला दुसऱ्या वेब स्क्रॅपरची गरज का आहे?

जेव्हा मी पहिल्यांदा वेब स्क्रॅपिंग सुरू केले, तेव्हा मला प्रामाणिकपणे त्यात विशेष रस नव्हता. मला भविष्यसूचक मॉडेलिंग, आर्थिक विश्लेषण आणि, शक्यतो, ग्रंथांच्या भावनिक रंगाचे विश्लेषण करण्याच्या क्षेत्रात आणखी प्रकल्प करायचे होते. परंतु असे दिसून आले की वेबसाइटवरून डेटा संकलित करणारा प्रोग्राम कसा तयार करायचा हे शोधणे खूप मनोरंजक आहे. मी या विषयाचा शोध घेत असताना, मला जाणवले की वेब स्क्रॅपिंग हे इंटरनेटचे "इंजिन" आहे.

तुम्हाला वाटेल की हे खूप धाडसी विधान आहे. परंतु Google ने जावा आणि पायथन वापरून लॅरी पेजने तयार केलेल्या वेब स्क्रॅपरपासून सुरुवात केली. Google रोबोट इंटरनेट एक्सप्लोर करत आहेत, त्यांच्या वापरकर्त्यांना त्यांच्या प्रश्नांची उत्तम उत्तरे देण्याचा प्रयत्न करत आहेत. वेब स्क्रॅपिंगचे अंतहीन उपयोग आहेत, आणि जरी तुम्हाला डेटा सायन्समधील इतर गोष्टींमध्ये स्वारस्य असले तरीही, तुम्हाला विश्लेषण करण्यासाठी आवश्यक असलेला डेटा मिळविण्यासाठी तुम्हाला काही स्क्रॅपिंग कौशल्ये आवश्यक असतील.

मला येथे वापरलेली काही तंत्रे अप्रतिम आढळली पुस्तक वेब स्क्रॅपिंग बद्दल, जे मी नुकतेच घेतले आहे. यात तुम्ही शिकलेल्या गोष्टींचा व्यावहारिक वापर करण्यासाठी अनेक साधी उदाहरणे आणि कल्पना आहेत. याव्यतिरिक्त, रीकॅप्चा चेक बायपास करण्यावर एक अतिशय मनोरंजक अध्याय आहे. ही माझ्यासाठी बातमी म्हणून आली, कारण अशा समस्यांचे निराकरण करण्यासाठी विशेष साधने आणि अगदी संपूर्ण सेवा आहेत हे मला माहित नव्हते.

तुम्हाला प्रवास करायला आवडते का?!

या विभागाच्या शीर्षकामध्ये विचारलेल्या सोप्या आणि निरुपद्रवी प्रश्नासाठी, ज्या व्यक्तीला हे विचारण्यात आले होते त्या व्यक्तीच्या प्रवासातील काही कथांसह आपणास सकारात्मक उत्तर ऐकू येते. आपल्यापैकी बरेच जण सहमत असतील की नवीन सांस्कृतिक वातावरणात स्वतःला विसर्जित करण्याचा आणि आपली क्षितिजे विस्तृत करण्याचा प्रवास हा एक चांगला मार्ग आहे. तथापि, जर तुम्ही कोणाला विचारले की त्यांना एअरलाइन तिकीट शोधणे आवडते का, तर मला खात्री आहे की उत्तर इतके सकारात्मक नसेल. खरं तर, पायथन इथे आमच्या मदतीला येतो.

हवाई तिकिटांवरील माहिती शोधण्यासाठी एक प्रणाली तयार करण्याच्या मार्गावर आम्हाला जे पहिले काम सोडवायचे आहे ते एक योग्य व्यासपीठ निवडणे आहे जिथून आम्ही माहिती घेऊ. ही समस्या सोडवणे माझ्यासाठी सोपे नव्हते, परंतु शेवटी मी कायक सेवा निवडली. मी Momondo, Skyscanner, Expedia आणि इतर काही सेवा वापरून पाहिल्या, परंतु या संसाधनांवरील रोबोट संरक्षण यंत्रणा अभेद्य होत्या. अनेक प्रयत्नांनंतर, ज्या दरम्यान मला ट्रॅफिक लाइट्स, पादचारी क्रॉसिंग आणि सायकलींचा सामना करावा लागला, मी माणूस आहे हे सिस्टमला पटवून देण्याचा प्रयत्न करत असताना, मी ठरवले की कयाक माझ्यासाठी सर्वात योग्य आहे, जरी खूप पृष्ठे लोड केली तरीही थोड्याच वेळात, आणि तपासण्या देखील सुरू होतात. मी बॉटला 4 ते 6 तासांच्या अंतराने साइटवर विनंत्या पाठवण्यास व्यवस्थापित केले आणि सर्व काही ठीक झाले. कयाक सोबत काम करताना वेळोवेळी अडचणी येतात, परंतु जर ते तुम्हाला चेकने त्रास देऊ लागले, तर तुम्हाला एकतर त्यांच्याशी मॅन्युअली डील करावी लागेल आणि नंतर बॉट लाँच करावे लागेल किंवा काही तास थांबावे लागेल आणि चेक थांबले पाहिजेत. आवश्यक असल्यास, आपण दुसर्‍या प्लॅटफॉर्मसाठी कोड सहजपणे जुळवून घेऊ शकता आणि आपण तसे केल्यास, आपण टिप्पण्यांमध्ये त्याची तक्रार करू शकता.

तुम्ही नुकतेच वेब स्क्रॅपिंगला सुरुवात करत असाल आणि काही वेबसाइट्स त्यासोबत का संघर्ष करत असाल हे माहित नसेल, तर तुम्ही या क्षेत्रात तुमचा पहिला प्रोजेक्ट सुरू करण्यापूर्वी, स्वतःला एक कृपा करा आणि "वेब स्क्रॅपिंग शिष्टाचार" या शब्दांवर Google सर्च करा. . तुम्ही वेब स्क्रॅपिंग अविवेकीपणे केल्यास तुमचे प्रयोग तुमच्या विचारापेक्षा लवकर संपू शकतात.

प्रारंभ करणे

आमच्या वेब स्क्रॅपर कोडमध्ये काय होईल याचे सामान्य विहंगावलोकन येथे आहे:

  • आवश्यक लायब्ररी आयात करा.
  • Google Chrome टॅब उघडत आहे.
  • तिकीट शोधताना वापरल्या जाणाऱ्या शहरे आणि तारखा पास करून बॉट सुरू करणारे फंक्शन कॉल करा.
  • हे कार्य प्रथम शोध परिणाम घेते, सर्वोत्तम नुसार क्रमवारी लावते आणि अधिक परिणाम लोड करण्यासाठी बटणावर क्लिक करते.
  • दुसरे फंक्शन संपूर्ण पृष्ठावरील डेटा संकलित करते आणि डेटा फ्रेम परत करते.
  • मागील दोन पायऱ्या तिकिटाच्या किमतीनुसार (स्वस्त) आणि उड्डाण गतीनुसार (सर्वात जलद) क्रमवारी लावल्या जातात.
  • स्क्रिप्ट वापरकर्त्याला तिकीटाच्या किमतींचा सारांश असलेला ईमेल (सर्वात स्वस्त तिकिटे आणि सरासरी किंमत) पाठवला जातो आणि वरील तीन मेट्रिक्सनुसार क्रमवारी लावलेली माहिती असलेली डेटा फ्रेम एक्सेल फाइल म्हणून सेव्ह केली जाते.
  • वरील सर्व क्रिया एका विशिष्ट कालावधीनंतर एका चक्रात केल्या जातात.

हे लक्षात घ्यावे की प्रत्येक सेलेनियम प्रकल्प वेब ड्रायव्हरसह सुरू होतो. मी वापरतो Chromedriver, मी Google Chrome सह कार्य करतो, परंतु इतर पर्याय आहेत. PhantomJS आणि Firefox देखील लोकप्रिय आहेत. ड्रायव्हर डाउनलोड केल्यानंतर, आपल्याला ते योग्य फोल्डरमध्ये ठेवणे आवश्यक आहे आणि हे त्याच्या वापरासाठी तयारी पूर्ण करते. आमच्या स्क्रिप्टच्या पहिल्या ओळी नवीन Chrome टॅब उघडतात.

लक्षात ठेवा की माझ्या कथेत मी हवाई तिकिटांवर उत्तम सौदे शोधण्यासाठी नवीन क्षितिजे उघडण्याचा प्रयत्न करीत नाही. अशा ऑफर शोधण्याच्या अनेक प्रगत पद्धती आहेत. मी या सामग्रीच्या वाचकांना या समस्येचे निराकरण करण्याचा एक सोपा परंतु व्यावहारिक मार्ग देऊ इच्छितो.

आम्ही वर बोललो तो कोड येथे आहे.

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)

कोडच्या सुरुवातीला तुम्ही पॅकेज इंपोर्ट कमांड पाहू शकता जे आमच्या संपूर्ण प्रोजेक्टमध्ये वापरले जातात. तर, randint नवीन शोध ऑपरेशन सुरू करण्यापूर्वी यादृच्छिक काही सेकंदांसाठी बॉटला "झोपी पडणे" करण्यासाठी वापरले जाते. सहसा, एकच बॉट याशिवाय करू शकत नाही. तुम्ही वरील कोड चालवल्यास, एक Chrome विंडो उघडेल, जी बॉट साइटसह कार्य करण्यासाठी वापरेल.

चला एक छोटासा प्रयोग करू आणि kayak.com वेबसाइट वेगळ्या विंडोमध्ये उघडू. आम्ही ज्या शहरातून उड्डाण करणार आहोत ते शहर आणि आम्हाला ज्या शहराला जायचे आहे, तसेच उड्डाणाच्या तारखा आम्ही निवडू. तारखा निवडताना, +-3 दिवसांची श्रेणी वापरली असल्याचे सुनिश्चित करा. अशा विनंत्यांना प्रतिसाद म्हणून साइट काय तयार करते हे लक्षात घेऊन मी कोड लिहिला. जर, उदाहरणार्थ, तुम्हाला फक्त निर्दिष्ट तारखांसाठी तिकिटे शोधण्याची आवश्यकता असेल, तर तुम्हाला बॉट कोड सुधारित करावा लागेल अशी उच्च शक्यता आहे. जेव्हा मी कोडबद्दल बोलतो, तेव्हा मी योग्य स्पष्टीकरण देतो, परंतु तुम्हाला गोंधळ वाटत असल्यास, मला कळवा.

आता सर्च बटणावर क्लिक करा आणि अॅड्रेस बारमधील लिंक पहा. ते खाली दिलेल्या उदाहरणात मी वापरत असलेल्या दुव्यासारखे असावे जेथे व्हेरिएबल घोषित केले आहे kayak, जे URL संग्रहित करते आणि पद्धत वापरली जाते get वेब ड्रायव्हर. शोध बटणावर क्लिक केल्यानंतर, परिणाम पृष्ठावर दिसले पाहिजेत.

पायथन - ज्यांना प्रवास करायला आवडते त्यांच्यासाठी स्वस्त हवाई तिकिटे शोधण्यात सहाय्यक
जेव्हा मी आज्ञा वापरली get काही मिनिटांत दोन किंवा तीनपेक्षा जास्त वेळा, मला reCaptcha वापरून सत्यापन पूर्ण करण्यास सांगितले गेले. तुम्ही हा चेक मॅन्युअली पास करू शकता आणि जोपर्यंत सिस्टम नवीन चेक चालवण्याचा निर्णय घेत नाही तोपर्यंत प्रयोग सुरू ठेवू शकता. जेव्हा मी स्क्रिप्टची चाचणी केली तेव्हा असे वाटले की पहिले शोध सत्र नेहमीच सुरळीत चालले होते, म्हणून जर तुम्हाला कोडचा प्रयोग करायचा असेल, तर तुम्हाला वेळोवेळी मॅन्युअली तपासावे लागेल आणि शोध सत्रांमधील दीर्घ अंतरांचा वापर करून कोड चालू द्यावा लागेल. आणि, आपण त्याबद्दल विचार केल्यास, एखाद्या व्यक्तीला शोध ऑपरेशन दरम्यान 10-मिनिटांच्या अंतराने प्राप्त झालेल्या तिकिटांच्या किमतींबद्दल माहितीची आवश्यकता नाही.

XPath वापरून पृष्ठासह कार्य करणे

म्हणून, आम्ही एक विंडो उघडली आणि साइट लोड केली. किंमत आणि इतर माहिती मिळविण्यासाठी, आम्हाला XPath तंत्रज्ञान किंवा CSS निवडक वापरण्याची आवश्यकता आहे. मी XPath वर टिकून राहण्याचा निर्णय घेतला आणि मला CSS निवडक वापरण्याची गरज वाटली नाही, परंतु अशा प्रकारे कार्य करणे शक्य आहे. XPath वापरून पृष्ठाभोवती नेव्हिगेट करणे अवघड असू शकते आणि जरी तुम्ही मी वर्णन केलेल्या तंत्रांचा वापर केला तरीही हे लेख, ज्यामध्ये पृष्ठ कोडवरून संबंधित अभिज्ञापक कॉपी करणे समाविष्ट होते, मला समजले की हा आवश्यक घटकांमध्ये प्रवेश करण्याचा इष्टतम मार्ग नाही. तसे, मध्ये हे पुस्तक XPath आणि CSS निवडक वापरून पृष्ठांसह कार्य करण्याच्या मूलभूत गोष्टींचे उत्कृष्ट वर्णन प्रदान करते. संबंधित वेब ड्रायव्हर पद्धत असे दिसते.

पायथन - ज्यांना प्रवास करायला आवडते त्यांच्यासाठी स्वस्त हवाई तिकिटे शोधण्यात सहाय्यक
तर, बॉटवर काम सुरू ठेवूया. सर्वात स्वस्त तिकिटे निवडण्यासाठी प्रोग्रामच्या क्षमतांचा वापर करूया. खालील इमेजमध्ये, XPath सिलेक्टर कोड लाल रंगात हायलाइट केला आहे. कोड पाहण्यासाठी, आपल्याला स्वारस्य असलेल्या पृष्ठ घटकावर उजवे-क्लिक करणे आवश्यक आहे आणि दिसत असलेल्या मेनूमधून तपासणी आदेश निवडा. हा आदेश वेगवेगळ्या पृष्ठ घटकांसाठी कॉल केला जाऊ शकतो, ज्याचा कोड कोड दर्शकामध्ये प्रदर्शित केला जाईल आणि हायलाइट केला जाईल.

पायथन - ज्यांना प्रवास करायला आवडते त्यांच्यासाठी स्वस्त हवाई तिकिटे शोधण्यात सहाय्यक
पृष्ठ कोड पहा

कोडमधून निवडक कॉपी करण्याच्या तोट्यांबद्दल माझ्या तर्काची पुष्टी शोधण्यासाठी, खालील वैशिष्ट्यांकडे लक्ष द्या.

तुम्ही कोड कॉपी करता तेव्हा तुम्हाला हे मिळते:

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

असे काहीतरी कॉपी करण्यासाठी, तुम्हाला स्वारस्य असलेल्या कोडच्या विभागावर उजवे-क्लिक करणे आवश्यक आहे आणि दिसत असलेल्या मेनूमधून कॉपी > कॉपी XPath कमांड निवडा.

सर्वात स्वस्त बटण परिभाषित करण्यासाठी मी जे वापरले ते येथे आहे:

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

पायथन - ज्यांना प्रवास करायला आवडते त्यांच्यासाठी स्वस्त हवाई तिकिटे शोधण्यात सहाय्यक
कमांड कॉपी करा > XPath कॉपी करा

हे अगदी स्पष्ट आहे की दुसरा पर्याय खूपच सोपा दिसतो. वापरल्यावर, ते गुणधर्म असलेल्या घटकाचा शोध घेते data-code, समान price. पहिला पर्याय वापरताना, घटक शोधला जातो id जे समान आहे wtKI-price_aTab, आणि घटकाचा XPath मार्ग असा दिसतो /div[1]/div/div/div[1]/div/span/span. पृष्ठावर यासारखी XPath क्वेरी युक्ती करेल, परंतु फक्त एकदाच. मी आत्ताच म्हणू शकतो id पुढील वेळी पृष्ठ लोड झाल्यावर बदलेल. वर्ण क्रम wtKI प्रत्येक वेळी पृष्ठ लोड केल्यावर गतिमानपणे बदलते, त्यामुळे पुढील पृष्ठ रीलोड झाल्यानंतर त्याचा वापर करणारा कोड निरुपयोगी होईल. त्यामुळे XPath समजून घेण्यासाठी थोडा वेळ घ्या. हे ज्ञान तुमची चांगली सेवा करेल.

तथापि, हे लक्षात घेतले पाहिजे की अगदी सोप्या साइट्सवर काम करताना XPath निवडक कॉपी करणे उपयुक्त ठरू शकते आणि जर तुम्हाला हे सोयीस्कर असेल, तर त्यात काहीही चुकीचे नाही.

आता सूचीमध्ये सर्व शोध परिणाम अनेक ओळींमध्ये मिळवायचे असल्यास काय करावे याचा विचार करूया. अगदी साधे. प्रत्येक परिणाम वर्गासह ऑब्जेक्टमध्ये असतो resultWrapper. सर्व परिणाम लोड करणे खाली दर्शविल्याप्रमाणे लूपमध्ये केले जाऊ शकते.

हे लक्षात घेतले पाहिजे की जर तुम्हाला वरील गोष्टी समजल्या असतील, तर आम्ही विश्लेषण करणार असलेल्या बहुतेक कोड तुम्हाला सहज समजले पाहिजेत. हा कोड चालू असताना, आम्ही काही प्रकारचे पथ-निर्दिष्ट यंत्रणा (XPath) वापरून आम्हाला आवश्यक असलेल्या गोष्टींमध्ये प्रवेश करतो (खरं तर, निकाल गुंडाळलेला घटक). हे घटकाचा मजकूर मिळविण्यासाठी आणि ते एका ऑब्जेक्टमध्ये ठेवण्यासाठी केले जाते ज्यामधून डेटा वाचता येतो (प्रथम वापरला जातो flight_containers, मग - flights_list).

पायथन - ज्यांना प्रवास करायला आवडते त्यांच्यासाठी स्वस्त हवाई तिकिटे शोधण्यात सहाय्यक
पहिल्या तीन ओळी प्रदर्शित केल्या आहेत आणि आम्हाला आवश्यक असलेली प्रत्येक गोष्ट आम्ही स्पष्टपणे पाहू शकतो. तथापि, आमच्याकडे माहिती मिळविण्याचे अधिक मनोरंजक मार्ग आहेत. आपल्याला प्रत्येक घटकाचा स्वतंत्रपणे डेटा घेणे आवश्यक आहे.

कामाला लागा!

फंक्शन लिहिण्याचा सर्वात सोपा मार्ग म्हणजे अतिरिक्त परिणाम लोड करणे, जेणेकरून आम्ही तेथून सुरुवात करू. तपासणीसाठी नेणाऱ्या सेवेमध्ये शंका निर्माण न करता, प्रोग्रामला माहिती मिळवणाऱ्या फ्लाइटची संख्या वाढवायची आहे, म्हणून प्रत्येक वेळी पृष्ठ प्रदर्शित झाल्यावर मी अधिक परिणाम लोड करा बटणावर क्लिक करतो. या कोडमध्ये, आपण ब्लॉककडे लक्ष दिले पाहिजे try, जे मी जोडले कारण कधीकधी बटण योग्यरित्या लोड होत नाही. तुम्‍हालाही हे आढळल्‍यास, फंक्‍शन कोडमध्‍ये या फंक्‍शनसाठी कॉल कमेंट करा start_kayak, जे आपण खाली पाहू.

# Загрузка большего количества результатов для того, чтобы максимизировать объём собираемых данных
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

आता, या फंक्शनच्या दीर्घ विश्लेषणानंतर (कधीकधी मी वाहून जाऊ शकतो), आम्ही एक फंक्शन घोषित करण्यास तयार आहोत जे पृष्ठ स्क्रॅप करेल.

खालील फंक्शनमध्ये जे आवश्यक आहे ते मी आधीच गोळा केले आहे page_scrape. कधीकधी परत केलेला पथ डेटा एकत्र केला जातो, म्हणून मी तो विभक्त करण्यासाठी एक सोपी पद्धत वापरतो. उदाहरणार्थ, जेव्हा मी पहिल्यांदा व्हेरिएबल्स वापरतो section_a_list и section_b_list. आमचे कार्य डेटा फ्रेम परत करते flights_df, हे आम्हाला वेगवेगळ्या डेटा क्रमवारी पद्धतींमधून मिळवलेले परिणाम वेगळे करण्यास आणि नंतर एकत्र करण्यास अनुमती देते.

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

मी व्हेरिएबल्सना नाव देण्याचा प्रयत्न केला जेणेकरून कोड समजेल. लक्षात ठेवा की व्हेरिएबल्सपासून सुरुवात होते a मार्गाच्या पहिल्या टप्प्याशी संबंधित आहेत आणि b - दुसऱ्याला. चला पुढच्या फंक्शनकडे जाऊ.

समर्थन यंत्रणा

आमच्याकडे आता एक कार्य आहे जे आम्हाला अतिरिक्त शोध परिणाम लोड करण्याची परवानगी देते आणि त्या परिणामांवर प्रक्रिया करण्यासाठी एक कार्य आहे. हा लेख येथे संपला असता, कारण ही दोन कार्ये तुम्हाला स्वतः उघडू शकणारी पृष्ठे स्क्रॅप करण्यासाठी आवश्यक असलेली प्रत्येक गोष्ट प्रदान करतात. परंतु आम्ही अद्याप वर चर्चा केलेल्या काही सहायक यंत्रणांचा विचार केलेला नाही. उदाहरणार्थ, हा ईमेल आणि इतर काही गोष्टी पाठवण्याचा कोड आहे. हे सर्व फंक्शनमध्ये आढळू शकते start_kayak, ज्याचा आपण आता विचार करू.

हे कार्य कार्य करण्यासाठी, तुम्हाला शहरे आणि तारखांविषयी माहिती हवी आहे. या माहितीचा वापर करून, ते व्हेरिएबलमध्ये एक दुवा तयार करते kayak, ज्याचा वापर तुम्हाला अशा पृष्ठावर नेण्यासाठी केला जातो ज्यामध्ये क्वेरीशी त्यांच्या सर्वोत्तम जुळणीनुसार क्रमवारी लावलेले शोध परिणाम असतील. पहिल्या स्क्रॅपिंग सत्रानंतर, आम्ही पृष्ठाच्या शीर्षस्थानी असलेल्या टेबलमधील किमतींसह कार्य करू. म्हणजे, आम्हाला तिकीटाची किमान किंमत आणि सरासरी किंमत मिळेल. हे सर्व, साइटद्वारे जारी केलेल्या अंदाजासह, ईमेलद्वारे पाठविले जाईल. पृष्ठावर, संबंधित सारणी वरच्या डाव्या कोपर्यात असावी. या सारणीसह कार्य करणे, तसे, अचूक तारखा वापरून शोधताना त्रुटी येऊ शकते, कारण या प्रकरणात टेबल पृष्ठावर प्रदर्शित होत नाही.

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 = '[email protected]'
    password = 'YOUR PASSWORD'

    server = smtplib.SMTP('smtp.outlook.com', 587)
    server.ehlo()
    server.starttls()
    server.login(username, password)
    msg = ('Subject: Flight Scrapernn
Cheapest Flight: {}nAverage Price: {}nnRecommendation: {}nnEnd of message'.format(matrix_min, matrix_avg, (loading+'n'+prediction)))
    message = MIMEMultipart()
    message['From'] = '[email protected]'
    message['to'] = '[email protected]'
    server.sendmail('[email protected]', '[email protected]', msg)
    print('sent email.....')

मी Outlook खाते (hotmail.com) वापरून या स्क्रिप्टची चाचणी केली. मी Gmail खात्यासह योग्यरित्या कार्य करण्यासाठी त्याची चाचणी केली नाही, ही ईमेल प्रणाली खूप लोकप्रिय आहे, परंतु बरेच संभाव्य पर्याय आहेत. आपण हॉटमेल खाते वापरत असल्यास, सर्वकाही कार्य करण्यासाठी, आपल्याला कोडमध्ये आपला डेटा प्रविष्ट करणे आवश्यक आहे.

या कार्यासाठी कोडच्या विशिष्ट विभागांमध्ये नेमके काय केले जात आहे हे तुम्हाला समजून घ्यायचे असल्यास, तुम्ही त्यांची कॉपी करू शकता आणि त्यांच्यासह प्रयोग करू शकता. कोडचा प्रयोग करणे हाच तो खऱ्या अर्थाने समजून घेण्याचा एकमेव मार्ग आहे.

तयार यंत्रणा

आता आम्ही जे काही बोललो ते पूर्ण केले आहे, आम्ही एक साधा लूप तयार करू शकतो जो आमच्या फंक्शन्सला कॉल करतो. स्क्रिप्ट वापरकर्त्याकडून शहरे आणि तारखांबद्दल डेटाची विनंती करते. स्क्रिप्टच्या सतत रीस्टार्टसह चाचणी करताना, तुम्हाला प्रत्येक वेळी हा डेटा व्यक्तिचलितपणे प्रविष्ट करण्याची शक्यता नाही, म्हणून चाचणीच्या वेळेसाठी, संबंधित ओळी, त्यांच्या खालील ओळींवर टिप्पणी न करता टिप्पणी केली जाऊ शकते, ज्यामध्ये डेटा आवश्यक आहे. स्क्रिप्ट हार्डकोड केलेली आहे.

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.....')

स्क्रिप्टची टेस्ट रन असे दिसते.
पायथन - ज्यांना प्रवास करायला आवडते त्यांच्यासाठी स्वस्त हवाई तिकिटे शोधण्यात सहाय्यक
स्क्रिप्टची चाचणी चालवणे

परिणाम

तुम्ही इथपर्यंत पोहोचला असाल, तर अभिनंदन! तुमच्याकडे आता कार्यरत वेब स्क्रॅपर आहे, जरी मी ते सुधारण्याचे बरेच मार्ग पाहू शकतो. उदाहरणार्थ, ते Twilio सह समाकलित केले जाऊ शकते जेणेकरून ते ईमेल ऐवजी मजकूर संदेश पाठवेल. एकाच वेळी अनेक सर्व्हरवरून परिणाम प्राप्त करण्यासाठी तुम्ही VPN किंवा दुसरे काहीतरी वापरू शकता. साइट वापरकर्ता व्यक्ती आहे की नाही हे तपासण्यासाठी वेळोवेळी उद्भवणारी समस्या देखील आहे, परंतु ही समस्या देखील सोडविली जाऊ शकते. कोणत्याही परिस्थितीत, आता आपल्याकडे एक आधार आहे जो आपण इच्छित असल्यास विस्तृत करू शकता. उदाहरणार्थ, एक्सेल फाइल वापरकर्त्याला ईमेलशी संलग्नक म्हणून पाठवली आहे याची खात्री करा.

पायथन - ज्यांना प्रवास करायला आवडते त्यांच्यासाठी स्वस्त हवाई तिकिटे शोधण्यात सहाय्यक

केवळ नोंदणीकृत वापरकर्तेच सर्वेक्षणात भाग घेऊ शकतात. साइन इन करा, आपले स्वागत आहे.

तुम्ही वेब स्क्रॅपिंग तंत्रज्ञान वापरता का?

  • होय

  • कोणत्याही

8 वापरकर्त्यांनी मतदान केले. 1 वापरकर्ता दूर राहिला.

स्त्रोत: www.habr.com

एक टिप्पणी जोडा