పైథాన్ - ప్రయాణం చేయడానికి ఇష్టపడే వారి కోసం చవకైన విమాన టిక్కెట్లను కనుగొనడంలో సహాయకుడు

ఈ రోజు మనం ప్రచురిస్తున్న వ్యాసం యొక్క రచయిత, దీని లక్ష్యం సెలీనియంను ఉపయోగించి పైథాన్‌లో ఎయిర్‌లైన్ టిక్కెట్ ధరల కోసం శోధించే వెబ్ స్క్రాపర్ అభివృద్ధి గురించి మాట్లాడటం దాని లక్ష్యం అని చెప్పారు. టిక్కెట్ల కోసం శోధిస్తున్నప్పుడు, సౌకర్యవంతమైన తేదీలు ఉపయోగించబడతాయి (+- పేర్కొన్న తేదీలకు సంబంధించి 3 రోజులు). స్క్రాపర్ శోధన ఫలితాలను Excel ఫైల్‌లో సేవ్ చేస్తుంది మరియు శోధనను అమలు చేసిన వ్యక్తికి వారు కనుగొన్న వాటి సారాంశంతో ఇమెయిల్‌ను పంపుతుంది. ఈ ప్రాజెక్ట్ యొక్క లక్ష్యం ప్రయాణికులు ఉత్తమమైన డీల్‌లను కనుగొనడంలో సహాయపడటం.

పైథాన్ - ప్రయాణం చేయడానికి ఇష్టపడే వారి కోసం చవకైన విమాన టిక్కెట్లను కనుగొనడంలో సహాయకుడు

మెటీరియల్‌ని అర్థం చేసుకున్నప్పుడు, మీరు కోల్పోయినట్లు అనిపిస్తే, ఒకసారి చూడండి వ్యాసం.

మనం దేని కోసం వెతకబోతున్నాం?

మీరు కోరుకున్న విధంగా ఇక్కడ వివరించిన సిస్టమ్‌ని ఉపయోగించడానికి మీకు స్వేచ్ఛ ఉంది. ఉదాహరణకు, వారాంతపు పర్యటనలు మరియు నా స్వస్థలానికి టిక్కెట్ల కోసం వెతకడానికి నేను దీనిని ఉపయోగించాను. మీరు లాభదాయకమైన టిక్కెట్‌లను కనుగొనడంలో తీవ్రంగా ఉంటే, మీరు సర్వర్‌లో స్క్రిప్ట్‌ను అమలు చేయవచ్చు (సరళమైనది సర్వర్, నెలకు 130 రూబిళ్లు, దీనికి చాలా అనుకూలంగా ఉంటుంది) మరియు ఇది రోజుకు ఒకటి లేదా రెండుసార్లు నడుస్తుందని నిర్ధారించుకోండి. శోధన ఫలితాలు మీకు ఇమెయిల్ ద్వారా పంపబడతాయి. అదనంగా, డ్రాప్‌బాక్స్ ఫోల్డర్‌లో శోధన ఫలితాలతో స్క్రిప్ట్ Excel ఫైల్‌ను సేవ్ చేసేలా అన్నింటినీ సెటప్ చేయాలని నేను సిఫార్సు చేస్తున్నాను, ఇది అటువంటి ఫైల్‌లను ఎక్కడి నుండైనా మరియు ఎప్పుడైనా వీక్షించడానికి మిమ్మల్ని అనుమతిస్తుంది.

పైథాన్ - ప్రయాణం చేయడానికి ఇష్టపడే వారి కోసం చవకైన విమాన టిక్కెట్లను కనుగొనడంలో సహాయకుడు
నేను ఇంకా ఎర్రర్‌లతో టారిఫ్‌లను కనుగొనలేదు, కానీ అది సాధ్యమేనని నేను భావిస్తున్నాను

శోధిస్తున్నప్పుడు, ఇప్పటికే పేర్కొన్నట్లుగా, “అనువైన తేదీ” ఉపయోగించబడుతుంది; స్క్రిప్ట్ ఇచ్చిన తేదీలలో మూడు రోజులలోపు ఆఫర్‌లను కనుగొంటుంది. స్క్రిప్ట్‌ను రన్ చేస్తున్నప్పుడు, ఇది ఒక దిశలో మాత్రమే ఆఫర్‌ల కోసం శోధిస్తుంది, అనేక విమాన దిశలలో డేటాను సేకరించేందుకు వీలుగా దానిని సవరించడం సులభం. దాని సహాయంతో, మీరు తప్పు టారిఫ్‌ల కోసం కూడా చూడవచ్చు; అటువంటి అన్వేషణలు చాలా ఆసక్తికరంగా ఉంటాయి.

మీకు మరొక వెబ్ స్క్రాపర్ ఎందుకు అవసరం?

నేను మొదట వెబ్ స్క్రాపింగ్‌ని ప్రారంభించినప్పుడు, నిజాయితీగా నేను దానిపై ప్రత్యేకించి ఆసక్తి చూపలేదు. నేను ప్రిడిక్టివ్ మోడలింగ్, ఫైనాన్షియల్ అనాలిసిస్ మరియు, బహుశా, టెక్స్ట్‌ల ఎమోషనల్ కలరింగ్‌ని విశ్లేషించే రంగంలో మరిన్ని ప్రాజెక్ట్‌లు చేయాలనుకుంటున్నాను. కానీ వెబ్‌సైట్ల నుండి డేటాను సేకరించే ప్రోగ్రామ్‌ను ఎలా సృష్టించాలో గుర్తించడం చాలా ఆసక్తికరంగా ఉందని తేలింది. నేను ఈ అంశాన్ని లోతుగా పరిశోధించినప్పుడు, వెబ్ స్క్రాపింగ్ అనేది ఇంటర్నెట్ యొక్క "ఇంజిన్" అని నేను గ్రహించాను.

ఇది చాలా బోల్డ్ స్టేట్‌మెంట్ అని మీరు అనుకోవచ్చు. అయితే జావా మరియు పైథాన్‌లను ఉపయోగించి లారీ పేజ్ సృష్టించిన వెబ్ స్క్రాపర్‌తో Google ప్రారంభించిందని పరిగణించండి. గూగుల్ రోబోట్‌లు ఇంటర్నెట్‌ను అన్వేషిస్తున్నాయి, దాని వినియోగదారుల ప్రశ్నలకు ఉత్తమ సమాధానాలను అందించడానికి ప్రయత్నిస్తున్నాయి. వెబ్ స్క్రాపింగ్ అంతులేని ఉపయోగాలను కలిగి ఉంది మరియు మీరు డేటా సైన్స్‌లో మరేదైనా ఆసక్తిని కలిగి ఉన్నప్పటికీ, మీరు విశ్లేషించాల్సిన డేటాను పొందడానికి మీకు కొన్ని స్క్రాపింగ్ నైపుణ్యాలు అవసరం.

ఇక్కడ ఉపయోగించిన కొన్ని టెక్నిక్‌లను నేను అద్భుతంగా కనుగొన్నాను పుస్తకం నేను ఇటీవల సంపాదించిన వెబ్ స్క్రాపింగ్ గురించి. మీరు నేర్చుకున్న వాటిని ఆచరణాత్మకంగా అన్వయించడానికి ఇది చాలా సాధారణ ఉదాహరణలు మరియు ఆలోచనలను కలిగి ఉంది. అదనంగా, reCaptcha తనిఖీలను దాటవేయడంపై చాలా ఆసక్తికరమైన అధ్యాయం ఉంది. అటువంటి సమస్యలను పరిష్కరించడానికి ప్రత్యేక సాధనాలు మరియు మొత్తం సేవలు కూడా ఉన్నాయని నాకు తెలియదు కాబట్టి ఇది నాకు వార్తగా వచ్చింది.

నువ్వు ప్రయాణించటానికి ఇస్తాపడతావా?!

ఈ విభాగం యొక్క శీర్షికలో సంధించిన సరళమైన మరియు హానిచేయని ప్రశ్నకు, మీరు ఎవరికి అడిగిన వ్యక్తి యొక్క ప్రయాణాల నుండి రెండు కథలతో పాటు సానుకూల సమాధానాన్ని తరచుగా వినవచ్చు. కొత్త సాంస్కృతిక వాతావరణాలలో మునిగిపోవడానికి మరియు మీ పరిధులను విస్తృతం చేసుకోవడానికి ప్రయాణం ఒక గొప్ప మార్గం అని మనలో చాలామంది అంగీకరిస్తారు. అయితే, మీరు విమాన టిక్కెట్ల కోసం వెతకడం ఇష్టపడతారా అని మీరు ఎవరినైనా అడిగితే, సమాధానం అంత సానుకూలంగా ఉండదని నేను ఖచ్చితంగా అనుకుంటున్నాను. వాస్తవానికి, పైథాన్ ఇక్కడ మాకు సహాయం చేస్తుంది.

విమాన టిక్కెట్లపై సమాచారాన్ని శోధించడానికి సిస్టమ్‌ను రూపొందించే మార్గంలో మనం పరిష్కరించాల్సిన మొదటి పని ఏమిటంటే, మేము సమాచారాన్ని తీసుకునే సరైన ప్లాట్‌ఫారమ్‌ను ఎంచుకోవడం. ఈ సమస్యను పరిష్కరించడం నాకు అంత సులభం కాదు, కానీ చివరికి నేను కయాక్ సేవను ఎంచుకున్నాను. నేను Momondo, Skyscanner, Expedia మరియు మరికొన్ని సేవలను ప్రయత్నించాను, కానీ ఈ వనరులపై రోబోట్ రక్షణ విధానాలు అభేద్యంగా ఉన్నాయి. అనేక ప్రయత్నాల తర్వాత, నేను ట్రాఫిక్ లైట్లు, పాదచారుల క్రాసింగ్‌లు మరియు సైకిళ్లతో వ్యవహరించాల్సి వచ్చింది, నేను మనిషిని అని సిస్టమ్‌లను ఒప్పించడానికి ప్రయత్నిస్తున్నాను, చాలా పేజీలు లోడ్ చేయబడినప్పటికీ, కయాక్ నాకు బాగా సరిపోతుందని నిర్ణయించుకున్నాను. తక్కువ సమయంలో, మరియు తనిఖీలు కూడా ప్రారంభమవుతాయి. నేను 4 నుండి 6 గంటల వ్యవధిలో సైట్‌కు అభ్యర్థనలను పంపేలా బోట్‌ని నిర్వహించగలిగాను మరియు ప్రతిదీ బాగానే పని చేసింది. కాలానుగుణంగా, కయాక్‌తో పనిచేసేటప్పుడు ఇబ్బందులు తలెత్తుతాయి, కానీ వారు మిమ్మల్ని చెక్‌లతో ఇబ్బంది పెట్టడం ప్రారంభిస్తే, మీరు వారితో మాన్యువల్‌గా వ్యవహరించి, ఆపై బోట్‌ను ప్రారంభించాలి లేదా కొన్ని గంటలు వేచి ఉండండి మరియు తనిఖీలు ఆగిపోతాయి. అవసరమైతే, మీరు మరొక ప్లాట్‌ఫారమ్ కోసం కోడ్‌ను సులభంగా స్వీకరించవచ్చు మరియు మీరు అలా చేస్తే, మీరు దానిని వ్యాఖ్యలలో నివేదించవచ్చు.

మీరు ఇప్పుడే వెబ్ స్క్రాపింగ్‌ని ప్రారంభిస్తుంటే మరియు కొన్ని వెబ్‌సైట్‌లు దానితో ఎందుకు కష్టపడుతున్నాయో తెలియకపోతే, మీరు ఈ ప్రాంతంలో మీ మొదటి ప్రాజెక్ట్‌ను ప్రారంభించే ముందు, మీకు సహాయం చేయండి మరియు "వెబ్ స్క్రాపింగ్ మర్యాద" అనే పదాలపై Google శోధన చేయండి. . మీరు తెలివితక్కువగా వెబ్ స్క్రాపింగ్ చేస్తే మీ ప్రయోగాలు మీరు అనుకున్న దానికంటే త్వరగా ముగియవచ్చు.

ప్రారంభ విధానం

మా వెబ్ స్క్రాపర్ కోడ్‌లో ఏమి జరుగుతుందనే సాధారణ అవలోకనం ఇక్కడ ఉంది:

  • అవసరమైన లైబ్రరీలను దిగుమతి చేసుకోండి.
  • Google Chrome ట్యాబ్‌ను తెరవడం.
  • టిక్కెట్ల కోసం శోధిస్తున్నప్పుడు ఉపయోగించబడే నగరాలు మరియు తేదీలను పాస్ చేస్తూ, బోట్‌ను ప్రారంభించే ఫంక్షన్‌కు కాల్ చేయండి.
  • ఈ ఫంక్షన్ ఉత్తమంగా క్రమబద్ధీకరించబడిన మొదటి శోధన ఫలితాలను తీసుకుంటుంది మరియు మరిన్ని ఫలితాలను లోడ్ చేయడానికి బటన్‌ను క్లిక్ చేస్తుంది.
  • మరొక ఫంక్షన్ మొత్తం పేజీ నుండి డేటాను సేకరిస్తుంది మరియు డేటా ఫ్రేమ్‌ను అందిస్తుంది.
  • మునుపటి రెండు దశలు టిక్కెట్ ధర (చౌకగా) మరియు విమాన వేగం (వేగవంతమైన) ద్వారా క్రమబద్ధీకరించడం ద్వారా నిర్వహించబడతాయి.
  • స్క్రిప్ట్ యొక్క వినియోగదారుకు టిక్కెట్ ధరల సారాంశాన్ని (చౌకైన టిక్కెట్‌లు మరియు సగటు ధర) కలిగి ఉన్న ఇమెయిల్ పంపబడుతుంది మరియు పైన పేర్కొన్న మూడు సూచికల ద్వారా క్రమబద్ధీకరించబడిన సమాచారంతో కూడిన డేటా ఫ్రేమ్ Excel ఫైల్‌గా సేవ్ చేయబడుతుంది.
  • పైన పేర్కొన్న అన్ని చర్యలు నిర్దిష్ట వ్యవధి తర్వాత ఒక చక్రంలో నిర్వహించబడతాయి.

ప్రతి సెలీనియం ప్రాజెక్ట్ వెబ్ డ్రైవర్‌తో ప్రారంభమవుతుందని గమనించాలి. నేను ఉపయోగిస్తాను 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ని కాపీ చేయండి

రెండవ ఎంపిక చాలా సరళంగా కనిపిస్తుందని చాలా స్పష్టంగా ఉంది. ఉపయోగించినప్పుడు, ఇది లక్షణం a మూలకం కోసం శోధిస్తుంది 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 ఖాతాతో సరిగ్గా పని చేయడానికి నేను దీన్ని పరీక్షించలేదు, ఈ ఇమెయిల్ సిస్టమ్ చాలా ప్రజాదరణ పొందింది, కానీ అనేక ఎంపికలు ఉన్నాయి. మీరు Hotmail ఖాతాను ఉపయోగిస్తుంటే, ప్రతిదీ పని చేయడానికి, మీరు మీ డేటాను కోడ్‌లో నమోదు చేయాలి.

ఈ ఫంక్షన్ కోసం కోడ్‌లోని నిర్దిష్ట విభాగాలలో సరిగ్గా ఏమి జరుగుతుందో మీరు అర్థం చేసుకోవాలనుకుంటే, మీరు వాటిని కాపీ చేసి వాటితో ప్రయోగాలు చేయవచ్చు. కోడ్‌తో ప్రయోగాలు చేయడం నిజంగా అర్థం చేసుకోవడానికి ఏకైక మార్గం.

సిద్ధంగా ఉన్న వ్యవస్థ

ఇప్పుడు మనం మాట్లాడిన ప్రతిదాన్ని పూర్తి చేసాము, మన ఫంక్షన్‌లను పిలిచే ఒక సాధారణ లూప్‌ను సృష్టించవచ్చు. స్క్రిప్ట్ నగరాలు మరియు తేదీల గురించి వినియోగదారు నుండి డేటాను అభ్యర్థిస్తుంది. స్క్రిప్ట్ యొక్క స్థిరమైన పునఃప్రారంభంతో పరీక్షిస్తున్నప్పుడు, మీరు ప్రతిసారీ ఈ డేటాను మాన్యువల్‌గా నమోదు చేయాలనుకునే అవకాశం లేదు, కాబట్టి సంబంధిత పంక్తులు, పరీక్ష సమయానికి, వాటి క్రింద ఉన్న వాటిని అన్‌కామెంట్ చేయడం ద్వారా వ్యాఖ్యానించవచ్చు, దీనిలో డేటా అవసరం స్క్రిప్ట్ హార్డ్‌కోడ్ చేయబడింది.

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

స్క్రిప్ట్ యొక్క టెస్ట్ రన్ ఇలా కనిపిస్తుంది.
పైథాన్ - ప్రయాణం చేయడానికి ఇష్టపడే వారి కోసం చవకైన విమాన టిక్కెట్లను కనుగొనడంలో సహాయకుడు
స్క్రిప్ట్ యొక్క టెస్ట్ రన్

ఫలితాలు

మీరు ఇంత దూరం చేసినట్లయితే, అభినందనలు! మీరు ఇప్పుడు పని చేసే వెబ్ స్క్రాపర్‌ని కలిగి ఉన్నారు, అయినప్పటికీ నేను దీన్ని మెరుగుపరచడానికి ఇప్పటికే అనేక మార్గాలను చూడగలను. ఉదాహరణకు, ఇది ట్విలియోతో అనుసంధానించబడుతుంది, తద్వారా ఇది ఇమెయిల్‌లకు బదులుగా వచన సందేశాలను పంపుతుంది. మీరు అనేక సర్వర్‌ల నుండి ఒకేసారి ఫలితాలను స్వీకరించడానికి VPN లేదా మరేదైనా ఉపయోగించవచ్చు. అతను ఒక వ్యక్తి కాదా అని చూడటానికి సైట్ వినియోగదారుని తనిఖీ చేయడంలో క్రమానుగతంగా తలెత్తే సమస్య కూడా ఉంది, అయితే ఈ సమస్య కూడా పరిష్కరించబడుతుంది. ఏదైనా సందర్భంలో, ఇప్పుడు మీరు కోరుకుంటే మీరు విస్తరించగల ఆధారాన్ని కలిగి ఉన్నారు. ఉదాహరణకు, ఎక్సెల్ ఫైల్ వినియోగదారుకు ఇమెయిల్‌కి అటాచ్‌మెంట్‌గా పంపబడిందని నిర్ధారించుకోండి.

పైథాన్ - ప్రయాణం చేయడానికి ఇష్టపడే వారి కోసం చవకైన విమాన టిక్కెట్లను కనుగొనడంలో సహాయకుడు

నమోదు చేసుకున్న వినియోగదారులు మాత్రమే సర్వేలో పాల్గొనగలరు. సైన్ ఇన్ చేయండిదయచేసి.

మీరు వెబ్ స్క్రాపింగ్ టెక్నాలజీలను ఉపయోగిస్తున్నారా?

  • అవును

8 మంది వినియోగదారులు ఓటు వేశారు. 1 వినియోగదారు దూరంగా ఉన్నారు.

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి