动态爬取携程网机票信息

最近在做有关交通城际出行领域的课题,需要用到一些关于机票的信息,于是就想到从携程网进行爬取相关数据。

但是呢,携程网它的票务信息查询后是一个动态页面,需要下拉才能返回更多的查询结果。所以这需要在一般的解析静态页面的爬虫方式上,增加一个浏览器的模拟器,来模拟下拉这一行为。

本次就是用到selenium这一个包的webdriver来模拟打开浏览器下拉这一行为。

话不多说,直接上代码和注释。

from bs4 import BeautifulSoup
import requests
import pandas as pd
import time
import lxml.html
from selenium import webdriver

def getFlightInfo(fromcity,tocity,date):
    url='https://flights.ctrip.com/itinerary/oneway/%s-%s?classType=ALL&ct=1606269725709&date=%s'%(fromcity,tocity,date)#携程的单程机票查询url
    #parse the html
    browser = webdriver.Chrome()
    browser.get(url)
    browser.implicitly_wait(30)#等一会儿,等信息解析
    browser.find_element_by_class_name('button').click()#模拟点击按钮
    browser.implicitly_wait(30)#多注意休息
    browser.find_element_by_class_name('dtime-sort').click()#模拟点击按时间排序按钮
    browser.implicitly_wait(30)
    browser.find_element_by_class_name('dtime-sort').click()#再模拟一次点击按时间排序按钮,确保出发时间从早到晚排序
    browser.implicitly_wait(30)
    time.sleep(3)

    # 获取页面初始高度
    js = "return action=document.body.scrollHeight"
    height = browser.execute_script(js)

    # 将滚动条调整至页面底部
    browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
    time.sleep(5)
    # 定义初始时间戳(秒)
    t1 = int(time.time())
    # 定义循环标识,用于终止while循环
    status = True
    # 重试次数
    num = 0
    while status:
        # 获取当前时间戳(秒)
        t2 = int(time.time())
        # 判断时间初始时间戳和当前时间戳相差是否大于30秒,小于30秒则下拉滚动条
        if t2 - t1 < 30:
            new_height = browser.execute_script(js)
            if new_height > height:
                time.sleep(1)
                browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
                # 重置初始页面高度
                height = new_height
                # 重置初始时间戳,重新计时
                t1 = int(time.time())
        elif num < 3:  # 当超过30秒页面高度仍然没有更新时,进入重试逻辑,重试3次,每次等待30秒
            time.sleep(3)
            num = num + 1
        else:  # 超时并超过重试次数,程序结束跳出循环,并认为页面已经加载完毕!
            print("滚动条已经处于页面最下方!")
            status = False
            # 滚动条调整至页面顶部
            browser.execute_script('window.scrollTo(0, 0)')
            break

 #要用到正则表达式
 flightnumber=browser.find_elements_by_css_selector(".search_table_header>.inb.logo>div>div>span>span>span")#空格设置为点,>层级关系,不可以跃层查询
    departtime=browser.find_elements_by_css_selector(".search_box.search_box_tag.search_box_light.Label_Flight>div>div>.inb.right>div.time_box")#空格设置为点,>层级关系
    departhub = browser.find_elements_by_css_selector(".search_box.search_box_tag.search_box_light.Label_Flight>div>div>.inb.right>div.airport")  # 空格设置为点
    arrivetime=browser.find_elements_by_css_selector(".search_box.search_box_tag.search_box_light.Label_Flight>div>div>.inb.left>div.time_box")#空格设置为点,>层级关系
    arrivehub = browser.find_elements_by_css_selector(".search_box.search_box_tag.search_box_light.Label_Flight>div>div>.inb.left>div.airport")  # 空格设置为点

    flightnumberlist=[content.text for content in flightnumber]
    flightnumberlist=list(filter(lambda x: x != '共享', flightnumberlist))#删除多余元素
    departtimelist=[content.text for content in departtime]
    departhublist=[content.text for content in departhub]
    arrivetimelist=[content.text for content in arrivetime]
    arrivehublist=[content.text for content in arrivehub]
    return flightnumberlist,departtimelist,departhublist,arrivetimelist,arrivehublist

if __name__ == '__main__':
    date='2020-11-27'
    fromcity='bjs'#查询北京到上海的机票
    tocity='sha'#查询北京到上海的机票
    path = '\\'
    flightnumberlist,departtimelist,departhublist,arrivetimelist,arrivehublist=getFlightInfo(fromcity, tocity, date)
    print(flightnumberlist)
    flightinfodict={'flightnumber':flightnumberlist,'departtime':departtimelist,'departhub':departhublist,
                        'arrivetime':arrivetimelist,'arrivehub':arrivehublist}
    flightinfodf=pd.DataFrame(flightinfodict)
    flightinfodf.to_csv(path+'%s-%s航空班次信息.csv'%(fromcity,tocity),encoding='utf_8_sig',index=False)
打赏
  • © 2020-2022 Eva Ren
  • Powered by Hexo Theme Ayer
    • 本站总访问量
    • 本页面总访问量
  • 载入运行时间...

请我喝杯咖啡吧~

支付宝
微信