携程:https://flights.ctrip.com/domestic/schedule/
这里我使用的是BeautifulSoup库。
所需模块:
import requests
from bs4 import BeautifulSoup
# 得到所有地方航班及链接
def getAllFlights():
flights = {} # {'安庆航班': 'https://flights.ctrip.com/schedule/aqg..html', ...}
url = 'https://flights.ctrip.com/schedule'
headers = {
'user-agent':random.choice(UserAgents),
'accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'accept-encoding':'gzip, deflate, br',
'accept-language':'zh-CN,zh;q=0.9',
'upgrade-insecure-requests':'1'
}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'lxml')
letter_list = soup.find( attrs={'class':'letter_list'} ).find_all('li')
for li in letter_list:
for a in li.find_all('a'):
flights[a.get_text()] = url + a['href'][9:]
return flights
这里的请求头user-agent是我从一个集合中随机获取的,也可以随便写一个。
返回的flights为一个字典,键为航班名称,值为链接。
# 得到一个地方航班的所有线路
def getFlightLines(url):
flightlines = {} # {'安庆-北京': 'http://flights.ctrip.com/schedule/aqg.bjs.html', ...}
headers = {
'Referer': 'https://flights.ctrip.com/schedule/',
'user-agent':random.choice(UserAgents)
}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'lxml')
letter_list = soup.find(attrs={'id': 'ulD_Domestic'}).find_all('li')
for li in letter_list:
for a in li.find_all('a'):
flightlines[a.get_text()] = a['href']
return flightlines
这个方法需要传入一个变量url,这个变量就是航班的链接,如:https://flights.ctrip.com/schedule/aqg..html
最后返回的flightlines是一个字典,键为线路名称,值为链接。
# 得到这条线路的所有航班信息
def getFlightInfo(url):
flightInfos = []
headers = {
'Host': 'flights.ctrip.com',
'user-agent': random.choice(UserAgents)
}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'lxml')
flights_tr = soup.find(attrs={'id':'flt1'}).find_all('tr')
for tr in flights_tr: # 遍历每个一航班
flightInfo = {}
info_td = tr.find_all('td')
# 航班编号
flight_no = info_td[0].find('strong').get_text().strip()
flightInfo['flight_no'] = flight_no
# 起飞时间
flight_stime = info_td[1].find('strong').get_text().strip()
flightInfo['flight_stime'] = flight_stime
# 起飞机场
flight_sairport = info_td[1].find('div').get_text().strip()
flightInfo['flight_sairport'] = flight_sairport
# 降落时间
flight_etime = info_td[3].find('strong').get_text().strip()
flightInfo['flight_etime'] = flight_etime
# 降落机场
flight_eairport = info_td[3].find('div').get_text().strip()
flightInfo['flight_eairport'] = flight_eairport
# 班期
flight_schedule = []
for s in info_td[4].find(attrs={'class':'week'}).find_all(name='span', attrs={'class':'blue'}):
flight_schedule.append(s.get_text().strip())
flight_schedule = ' '.join( flight_schedule )
flightInfo['flight_schedule'] = flight_schedule
# 准点率
flight_punrate = info_td[5].get_text().strip()
flightInfo['flight_punrate'] = flight_punrate
# 价格
flight_price = info_td[6].get_text().strip()
flightInfo['flight_price'] = flight_price
flightInfos.append(flightInfo)
return flightInfos
实现起来并不复杂,关键的地方我都已写好了注释。
我们只需要传入一条线路的url给这个方法,即可获得该条线路所有的航班信息,这个方法返回的是一个集合,集合中存放字典,字典中存放着航班编号、起飞时间等信息。
到此所需要的方法都已经封装好了,最后梳理一下流程:
1、调用getAllFlights()方法,得到所有的地方航班;
2、循环取出每一个地方航班,把每一个地方航班的链接传到getFlightLines()方法中,得到该地方航班的所有线路;
3、循环取出每一条线路,把每一条线路的链接传到getFlightInfo()方法中,得到该条线路的所有的航班信息;
4、循环取出每一个航班信息,进行数据库存储等操作。
这里只是根据我的需求来进行的代码编写和数据库的存储,有需要的朋友可以参考以下代码的逻辑处理来满足自己的需求。
好啦,到此所有的流程均已结束。
以上代码并不是最优的,可以根据实际使用进优化。
注意:以上内容仅供学习交流使用,请勿用于违法目的。