爬蟲 — 爬取攜程的航班資訊
阿新 • • 發佈:2018-12-20
功能介紹:輸入起點、終點、時間就能得到攜程上的航班資訊
程式碼:
from prettytable import PrettyTable import requests import json def xiecheng(dcity,acity,date): date = date[0:4]+'-'+date[4:6]+'-'+date[6:8] headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36", "Content-Type": "application/json",# 宣告文字型別為 json 格式 } city = {'阿爾山': 'YIE', '阿克蘇': 'AKU', '阿拉善右旗': 'RHT', '阿拉善左旗': 'AXF', '阿勒泰': 'AAT', '阿里': 'NGQ', '澳門': 'MFM', '安慶': 'AQG', '安順': 'AVA', '鞍山': 'AOG', '巴彥淖爾': 'RLK', '百色': 'AEB', '包頭': 'BAV', '保山': 'BSD', '北海': 'BHY', '北京': 'BJS', '白城': 'DBC', '白山': 'NBS', '畢節': 'BFJ', '博樂': 'BPL', '重慶': 'CKG', '昌都': 'BPX', '常德': 'CGD', '常州': 'CZX', '朝陽': 'CHG', '成都': 'CTU', '池州': 'JUH', '赤峰': 'CIF', '揭陽': 'SWA', '長春': 'CGQ', '長沙': 'CSX', '長治': 'CIH', '承德': 'CDE', '滄源': 'CWJ', '達縣': 'DAX', '大理': 'DLU', '大連': 'DLC', '大慶': 'DQA', '大同': 'DAT', '丹東': 'DDG', '稻城': 'DCY', '東營': 'DOY', '敦煌': 'DNH', '芒市': 'LUM', '額濟納旗': 'EJN', '鄂爾多斯': 'DSN', '恩施': 'ENH', '二連浩特': 'ERL', '佛山': 'FUO', '福州': 'FOC', '撫遠': 'FYJ', '阜陽': 'FUG', '贛州': 'KOW', '格爾木': 'GOQ', '固原': 'GYU', '廣元': 'GYS', '廣州': 'CAN', '貴陽': 'KWE', '桂林': 'KWL', '哈爾濱': 'HRB', '哈密': 'HMI', '海口': 'HAK', '海拉爾': 'HLD', '邯鄲': 'HDG', '漢中': 'HZG', '杭州': 'HGH', '合肥': 'HFE', '和田': 'HTN', '黑河': 'HEK', '呼和浩特': 'HET', '淮安': 'HIA', '懷化': 'HJJ', '黃山': 'TXN', '惠州': 'HUZ', '雞西': 'JXA', '濟南': 'TNA', '濟寧': 'JNG', '加格達奇': 'JGD', '佳木斯': 'JMU', '嘉峪關': 'JGN', '金昌': 'JIC', '金門': 'KNH', '錦州': 'JNZ', '嘉義': 'CYI', '西雙版納': 'JHG', '建三江': 'JSJ', '晉江': 'JJN', '井岡山': 'JGS', '景德鎮': 'JDZ', '九江': 'JIU', '九寨溝': 'JZH', '喀什': 'KHG', '凱里': 'KJH', '康定': 'KGT', '克拉瑪依': 'KRY', '庫車': 'KCA', '庫爾勒': 'KRL', '昆明': 'KMG', '拉薩': 'LXA', '蘭州': 'LHW', '黎平': 'HZH', '麗江': 'LJG', '荔波': 'LLB', '連雲港': 'LYG', '六盤水': 'LPF', '臨汾': 'LFQ', '林芝': 'LZY', '臨滄': 'LNJ', '臨沂': 'LYI', '柳州': 'LZH', '瀘州': 'LZO', '洛陽': 'LYA', '呂梁': 'LLV', '瀾滄': 'JMJ', '龍巖': 'LCX', '滿洲里': 'NZH', '梅州': 'MXZ', '綿陽': 'MIG', '漠河': 'OHE', '牡丹江': 'MDG', '馬祖': 'MFK', '南昌': 'KHN', '南充': 'NAO', '南京': 'NKG', '南寧': 'NNG', '南通': 'NTG', '南陽': 'NNY', '寧波': 'NGB', '寧蒗': 'NLH', '攀枝花': 'PZI', '普洱': 'SYM', '齊齊哈爾': 'NDG', '黔江': 'JIQ', '且末': 'IQM', '秦皇島': 'BPE', '青島': 'TAO', '慶陽': 'IQN', '衢州': 'JUZ', '日喀則': 'RKZ', '日照': 'RIZ', '三亞': 'SYX', '廈門': 'XMN', '上海': 'SHA', '深圳': 'SZX', '神農架': 'HPG', '瀋陽': 'SHE', '石家莊': 'SJW', '塔城': 'TCG', '台州': 'HYN', '太原': 'TYN', '揚州': 'YTY', '唐山': 'TVS', '騰衝': 'TCZ', '天津': 'TSN', '天水': 'THQ', '通遼': 'TGO', '銅仁': 'TEN', '吐魯番': 'TLQ', '萬州': 'WXN', '威海': 'WEH', '濰坊': 'WEF', '溫州': 'WNZ', '文山': 'WNH', '烏海': 'WUA', '烏蘭浩特': 'HLH', '烏魯木齊': 'URC', '無錫': 'WUX', '梧州': 'WUZ', '武漢': 'WUH', '武夷山': 'WUS', '西安': 'SIA', '西昌': 'XIC', '西寧': 'XNN', '錫林浩特': 'XIL', '香格里拉(迪慶)': 'DIG', '襄陽': 'XFN', '興義': 'ACX', '徐州': 'XUZ', '香港': 'HKG', '煙臺': 'YNT', '延安': 'ENY', '延吉': 'YNJ', '鹽城': 'YNZ', '伊春': 'LDS', '伊寧': 'YIN', '宜賓': 'YBP', '宜昌': 'YIH', '宜春': 'YIC', '義烏': 'YIW', '銀川': 'INC', '永州': 'LLF', '榆林': 'UYN', '玉樹': 'YUS', '運城': 'YCU', '湛江': 'ZHA', '張家界': 'DYG', '張家口': 'ZQZ', '張掖': 'YZY', '昭通': 'ZAT', '鄭州': 'CGO', '中衛': 'ZHY', '舟山': 'HSN', '珠海': 'ZUH', '遵義(茅臺)': 'WMT', '遵義(新舟)': 'ZYI'} url = 'http://flights.ctrip.com/itinerary/api/12808/products' request_payload = {"flightWay":"Oneway", "classType":"ALL", "hasChild":'false', "hasBaby":'false', "searchIndex":1, "portingToken":"3fec6a5a249a44faba1f245e61e2af88", "airportParams":[{"dcity":city.get(dcity),"acity":city.get(acity),"dcityname":dcity,"acityname":acity,"date":date}]} # 這裡傳進去的引數必須為 json 格式 response = requests.post(url,data=json.dumps(request_payload),headers=headers).text routeList = json.loads(response).get('data').get('routeList') table=PrettyTable(["Airline","FlightNumber","DepartureDate",'ArrivalDate','PunctualityRate','LowestPrice']) for route in routeList: if len(route.get('legs')) == 1: info = {} legs = route.get('legs')[0] flight = legs.get('flight') info['Airline'] = flight.get('airlineName') info['FlightNumber'] = flight.get('flightNumber') info['DepartureDate'] = flight.get('departureDate')[-8:-3] info['ArrivalDate'] = flight.get('arrivalDate')[-8:-3] info['PunctualityRate'] = flight.get('punctualityRate') info['LowestPrice'] = legs.get('characteristic').get('lowestPrice') table.add_row(info.values()) print(dcity,'------->',acity,date) print(table) if __name__ == "__main__": dcity = input('請輸入起點: ') acity = input('請輸入終點: ') date = input('請輸入出行日期: ') xiecheng(dcity,acity,date)
註釋:
- 訪問的連結為 post 請求,發現傳遞的引數型別不是Form Data,而是Request Payload。百度查到一篇文章得到解釋,這個型別需要傳入的是 json 格式的引數,且需要在 headers 裡面宣告,才能正常的傳遞引數訪問連結。
- 傳入的時間引數應該是 8 位數的時間格式。
- 這裡沒有對傳入的地點和時間進行判斷,所以輸入的地點應該在 city 字典中,且時間不早於當期日期。
- 核對爬出來的資料都與網頁上的一樣,但不排除攜程在裡面投毒的可能性,比如去哪兒網。
關於 Request Payload 參考文章:
爬取結果: