Введение
Всем читающим этот пост — здравствуйте.
Авиация — мое хобби, я об этом уже
писал. Я готов часами стоять и фотографировать самолеты, смотреть видео о них, читать блоги летчиков, следить за трафиком на
fr24.com. А еще мне нравится то, что в авиации кругом одни сокращения: ECAM, CDA, ACESS, APU и так далее. Вообщем, магия. А вот почти все люди из моего окружения к авиации равнодушны: «Ну самолет, как самолет. Большой, да. Что? Boeing 777-300ER? Ну ясно, ясно...». Но ничего не поделаешь, на вкус и цвет все фломастеры разные.
Как ко мне пришла идея поста? Так получилось, что я живу в 20 минутах езды от аэропорта Шереметьево. Как-то у меня выдался свободный час и приехал немного пофотографировать. За то время, пока я там был, мимо меня пролетело около 10 самолетов. Почти все — Аэрофлот. Я не спорю, у Аэрофлота есть интересные борты. Например,
Добролет или
Хохлома. Но в тот день мне не повезло, ничего подобного я не увидел. И тогда я подумал, что было бы очень полезно планировать подобные выезды. Вот так вот и родилась идея поста. Мне хотелось иметь следующий функционал: таблица вылетов — прилетов для выбранного аэропорта, выделение цветом как интересных, так и не очень ботов, экспорт в pdf.
Начинаем!
Итак, первым делом необходимо зайти на
https://developer.flightstats.com, зарегистрироваться, перейти в Dashboard и нажать на кнопку «Create a new application». Это необходимо для получения связки AppId + AppKey, без которой доступ к API невозможен. Вообще, оно платное, но присутствует и бесплатный тарифный план — "
Evaluation Plan", его возможностей для наших нужд хватит сполна. После этого смело идем "
Get Started" -> "
Flex API Reference" -> "
Flight Status & Track API" -> "
Flight Status & Track by Airport". В нижней части страницы есть раздел "
Interactive Documentation", выбираем "
Airport status (departures)". В данном запросе есть 7 обязательных полей, которые необходимо заполнить следующим образом:
appId |
appKey |
airport |
year |
month |
day |
hourOfDay |
Ваш appId |
Ваш appKey |
SVO |
2013 |
12 |
7 |
10 |
Через пару секунд появится ответ.
Иными словами мы попросили выдать нам информацию о рейсах, которые вылетят 7 декабря 2014 года после 10 часов из аэропорта Шереметьево. Да, SVO — Шереметьево. А еще UUEE — тоже Шереметьево. Помните, чуть выше я говорил о сокращениях? Вот, мы наткнулись на первое.
Коды аэропортов. IATA vs. ICAO
IATA — Международная ассоциация воздушного транспорта,
ИАТА (англ. International Air Transport Association) международная неправительственная организация. Ассоциация выступает координатором и представителем интересов авиатранспортной отрасли в таких областях как обеспечение безопасности полетов, производство полетов, тарифная политика, техобслуживание, авиационная безопасность, разработка международных стандартов совместно с ИКАО и т. д.
ICAO — Международная организация гражданской авиации (International Civil Aviation Organization) — специализированное учреждение ООН, устанавливающее международные нормы гражданской авиации и координирующее её развитие с целью повышения безопасности и эффективности.
И у ИАТА и у ИКАО есть свои коды аэропортов. Они различны, поскольку коды ИАТА выбираются созвучными с названием аэропорта, а код ИКАО основан на том, где находится аэропорт. Именно поэтому у Шереметево код ИАТА SVO, а ИКАО — UUEE, для Пулково, например, LED и ULLI соответственно. Исключение составляют лишь аэропорты США (добавляется «K» к коду ИАТА: Лос-Анджелес — LAX — KLAX) и Канады (добавляется «С»: Торонто — YYZ — CYYZ).
Ответ flightstats
При данном запросе ответ имеет следующую структуру:
{
посланный запрос
}
"appendix":
{
"airlines": {...}
"airports": {...}
"equipments": {...}
"flightStatuses": {...}
}
Секции
airlines,
airports и
equipments содержат в себе описание авиакомпаний, аэропортов и типов самолетов, которые присутствуют в секции flightStatuses.
Секция «airlines» предельно проста:
"airlines": [
{
"fs": "SU",
"iata": "SU",
"icao": "AFL",
"name": "Aeroflot",
"active": true
},
...
Поле «fs» содержит в себе код авиакомпании в базе flightStats. Почти всегда он совпадает с кодом IATA.
Секция «airports» посложнее:
"airports": [
{
"fs": "BUD",
"iata": "BUD",
"icao": "LHBP",
"name": "Liszt Ferenc International Airport",
"city": "Budapest",
"cityCode": "BUD",
"countryCode": "HU",
"countryName": "Hungary",
"regionName": "Europe",
"timeZoneRegionName": "Europe/Budapest",
"localTime": "2013-12-06T20:51:56.974",
"utcOffsetHours": 1,
"latitude": 47.433037,
"longitude": 19.261621,
"elevationFeet": 495,
"classification": 2,
"active": true,
"delayIndexUrl": "https://api.flightstats.com/flex/delayindex/rest/v1/json/airports/BUD?codeType=fs",
"weatherUrl": "https://api.flightstats.com/flex/weather/rest/v1/json/all/BUD?codeType=fs"
},
...
Здесь содержится вся необходимая информация, кроме погоды и коэффициента задержки, которые надо запрашивать отдельно.
Секция «equipments».
"equipments": [
{
"iata": "319",
"name": "Airbus Industrie A319",
"turboProp": false,
"jet": true,
"widebody": false,
"regional": false
},
...
Описывает базовые характеристики самолета.
Отвлечемся вновь от API.
Учимся различать типы самолетов
Это совсем не сложно. Я подготовил небольшую схему, которая поможет легко сориентироваться в мире летающих машин.
И теперь подтвержение моих слов:
Airbus A380 vs. Boeing 747
Airbus A340
Boeing 737 vs. Airbus A320
Boeing 757 vs. Boeing 767
Airbus A330 vs. Boeing 777
McDonnel Douglas MD-11
Разбираем flightStatus
Срдержимое flightStatus. Длинное, поэтому скрыто
{
"flightId": 317846653,
"carrierFsCode": "SU",
"flightNumber": "2030",
"departureAirportFsCode": "SVO",
"arrivalAirportFsCode": "BUD",
"departureDate": {
"dateLocal": "2013-12-07T10:50:00.000",
"dateUtc": "2013-12-07T06:50:00.000Z"
},
"arrivalDate": {
"dateLocal": "2013-12-07T10:35:00.000",
"dateUtc": "2013-12-07T09:35:00.000Z"
},
"status": "L",
"schedule": {
"flightType": "J",
"serviceClasses": "RJY",
"restrictions": ""
},
"operationalTimes": {
"publishedDeparture": {
"dateLocal": "2013-12-07T10:50:00.000",
"dateUtc": "2013-12-07T06:50:00.000Z"
},
"publishedArrival": {
"dateLocal": "2013-12-07T10:35:00.000",
"dateUtc": "2013-12-07T09:35:00.000Z"
},
"scheduledGateDeparture": {
"dateLocal": "2013-12-07T10:50:00.000",
"dateUtc": "2013-12-07T06:50:00.000Z"
},
"estimatedGateDeparture": {
"dateLocal": "2013-12-07T10:50:00.000",
"dateUtc": "2013-12-07T06:50:00.000Z"
},
"actualGateDeparture": {
"dateLocal": "2013-12-07T11:27:00.000",
"dateUtc": "2013-12-07T07:27:00.000Z"
},
"scheduledGateArrival": {
"dateLocal": "2013-12-07T10:35:00.000",
"dateUtc": "2013-12-07T09:35:00.000Z"
},
"estimatedGateArrival": {
"dateLocal": "2013-12-07T11:12:00.000",
"dateUtc": "2013-12-07T10:12:00.000Z"
},
"actualGateArrival": {
"dateLocal": "2013-12-07T10:43:00.000",
"dateUtc": "2013-12-07T09:43:00.000Z"
}
},
"delays": {
"departureGateDelayMinutes": 37,
"arrivalGateDelayMinutes": 8
},
"flightDurations": {
"scheduledBlockMinutes": 165,
"blockMinutes": 136
},
"airportResources": {
"departureTerminal": "D",
"departureGate": "28",
"arrivalTerminal": "2"
},
"flightEquipment": {
"scheduledEquipmentIataCode": "320",
"actualEquipmentIataCode": "A320",
"tailNumber": "VP-BWI"
}
},
...
Назначение полей в большинстве случаев очевидно. Я подробно расскажу лишь о тех, содержимое которых не совсем очевидно. А почему? Правильно, потому что сокращения.
Вот эта часть ответа:
"status": "L",
"schedule": {
"flightType": "J",
"serviceClasses": "RJY",
"restrictions": ""
},
Поле |
Описание |
status |
Текущий статус рейса
A — Active
C — Canceled
D — Diverted — Была произведена смена пункта назначения (например, по метео-условиям)
DN — Data source needed — Неоткуда получить информацию о статусе
L — Landed
NO — Not Operational
R — Redirected
S — Scheduled
U — Unknown |
flightType |
Тип рейса. Всего их существует 23 штуки. Например,
J — Scheduled Passanger — Пассажириский по расписанию
M — Scheduled Cargo/Mail(MailOnly) — Грузовой, но только с письмами.
W — Military — Военный |
serviceClasses |
Варианты сервиса, предусмотренные на рейсе по классификации IATA. Подробнее тут — http://en.wikipedia.org/wiki/IATA_class_codes |
restrictions |
Ограничения по классификации IATA. Подробнее — http://www.flyerguide.com/wiki/index.php/Traffic_Restriction_Codes_(AA) |
Программирование
На данный момент я использую python 2.7, urllib2 и simplejson.
Первое, что нужно сделать — подключить необходимые библиотеки и проинициализировать переменные.
import urllib2
import simplejson
appId = "Ваш appId тут"
appKey = "Ваш appKey тут"
# Название аэропорта. Может быть запрошен как по внутреннему коду flightstats, так и по кодам ICAO или IATA
requestedAirport = "SVO"
# Какие рейсы нам нужны. arr - прибывающие, dep - отбывающие
flightsType = "arr"
# Дата
requestedDate = "2013/12/7"
# Время, с которого мы хотим получить список рейсов
requestedHour = "15"
# Количество часов, за которые будет составлен список
requestedNumHours = "6"
Следующий шаг — упаковываем эти переменные в url, отправляем запрос и ждем ответа.
# Заготовка для запроса
url = "https://api.flightstats.com/flex/flightstatus/rest/v2/json/" \
"airport/status/%s/%s/%s/%s?appId=%s&appKey=%s&utc=false&numHours=%s"
# Подставляем нужные значения в запрос
url = url %(requestedAirport, flightsType, requestedDate, requestedHour, appId, appKey, requestedNumHours)
# Шлем запрос и получаем JSON-ответ
req = urllib2.Request(url, None)
opener = urllib2.build_opener()
f = opener.open(req)
response = simplejson.load(f)
Затем парсим вспомогательные поля. Они нам нужны для того, чтобы подставлять развернутые названия самолетов и аэропотов в список.
# Сохраняем ветку с аэропортами
airports = response["appendix"]["airports"]
# Данные по аэропортам будут храниться в словаре (dictionary)
airportsDict = dict()
# Для каждого аэропорта записываем пару [код flightstats]:[название]
for airport in airports:
airportsDict[airport["fs"]] = airport["name"]
# Аналогично поступаем для типов бортов...
equipments = response["appendix"]["equipments"]
equipmentsDict = dict()
for equipment in equipments:
equipmentsDict[equipment["iata"]] = equipment["name"], equipment["iata"]
#... и для авиакомпаний
airlines = response["appendix"]["airlines"]
airlinesDict = dict()
for airline in airlines:
airlinesDict[airline["fs"]] = airline["name"]
Результатом работы нашего кода должна быть вот такая таблица:
Flight |
Carrier |
Equipment |
Registration |
From |
STD |
ATD |
To |
STA |
STD |
---|
XQ114 |
SunExpress |
Boeing 737-800 Passenger |
D-ASXA |
Antalya |
15:00:00.000 |
--- |
CGN |
17:55:00.000 |
--- |
Выводить данные будем в HTML.
# Заготовка для страницы
webPage = "<html><body><table border=\"1\"> \
<tr><th>Flight</th><th>Carrier</th><th>Equipment</th><th>Registration</th><th>From</th><th>STD</th> \
<th>ATD</th><th>To</th><th>STA</th><th>ETA</th></tr>"
# Заготовка для строки таблицы
templateRow = "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td> \
<td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>"
f = open("./list.html", "w")
Далее необходимо написать вспомогательную функцию.
Нужные нам значения лежат на разной глубине. Например, carrierFsCode
, код аэропорта, на нулевой глубине. А чтобы добыть время фактическое время вылета, нужно опуститься на вторую глубину: operationalTimes --> actualGateDeparture --> dateLocal"
. Для этого нужна первая вспомогательная функция.
def getProperty(status, propertyNames):
# Cохраняем все содержимое status
property = status
# Пытаемся найти нужный ключ
try:
# Перебираем каждый ключ из propertyNames
for propertyName in propertyNames:
# Отсекаем ненужное
property = property[propertyName]
# Нужный ключ найден!
return property
except
# А если нет, то возвращаем заглушку
return "---"
Теперь самое интересное: необходимо выбрать то, что вас наиболее интересует в трафике. Это содержится в трех массивах:
interestingCarriers = ["RU", # AirBridgeCargo
"CU", # Cubana de Aviacion
"ME", # China Eastern Airlines
"KE", # Korean Air Lines
]
interestingEquipments = ["SU9"] # Sukhoi Superjet 100
interestingTailNumbers = ["VP-BGB"] # Номер первого Boeing 777-300ER для Аэрофлота
А теперь, собственно, парсер:
for flightStatus in flightStatuses:
newRow = templateRow %(getProperty(flightStatus, ["carrierFsCode"]) + getProperty(flightStatus, ["flightNumber"]),
airlinesDict[getProperty(flightStatus, ["carrierFsCode"])],
getProperty(flightStatus, ["flightEquipment", "scheduledEquipmentIataCode"]),
getProperty(flightStatus, ["flightEquipment", "tailNumber"]),
str(airportsDict[getProperty(flightStatus, ["departureAirportFsCode"])]).replace("Airport", ""),
str(getProperty(flightStatus, ["departureDate", "dateLocal"])).split("T")[-1],
str(getProperty(flightStatus, ["operationalTimes", "actualGateDeparture", "dateLocal"])).split("T")[-1],
str(airportsDict[getProperty(flightStatus, ["arrivalAirportFsCode"])]).replace("Airport", "")
str(getProperty(flightStatus, ["arrivalDate", "dateLocal"])).split("T")[-1],
str(getProperty(flightStatus, ["operationalTimes", "estimatedGateArrival", "dateLocal"])).split("T")[-1])
# Подсвечиваем необходимую строку
if (getProperty(flightStatus, ["carrierFsCode"]) in interestingCarriers) or \
(getProperty(flightStatus, ["flightEquipment", "scheduledEquipmentIataCode"]) in interestingEquipments) or \
(getProperty(flightStatus, ["flightEquipment", "tailNumber"]) in interestingTailNumbers):
newRow = newRow.replace("<tr>", "<tr bgcolor=\"#FF0000\">")
# Добавляем ее к странице
webPage += newRow
Завершающий штрих — дописываем теги в конец страницы и закрываем файл.
webPage = webPage + "</table></body></html>"
f.write(webPage)
f.close()
Результат работы
Flight |
Carrier |
Equipment |
Registration |
From |
STD |
ATD |
To |
STA |
ETA |
---|
SU155 |
Aeroflot |
332 |
VQ-BBE |
Cancun International |
12:30:00.000 |
13:17:00.000 |
Sheremetyevo International |
10:30:00.000 |
11:03:00.000 |
DL466 |
Delta Air Lines |
76W |
--- |
John F. Kennedy International |
16:15:00.000 |
16:14:00.000 |
Sheremetyevo International |
10:50:00.000 |
10:12:00.000 |
SU111 |
Aeroflot |
332 |
VP-BLX |
Miami International |
17:35:00.000 |
18:35:00.000 |
Sheremetyevo International |
13:45:00.000 |
13:46:00.000 |
SU103 |
Aeroflot |
333 |
VP-BDE |
John F. Kennedy International |
19:05:00.000 |
--- |
Sheremetyevo International |
13:25:00.000 |
13:34:00.000 |
UN576 |
Transaero Airlines |
744 |
EI-XLJ |
Punta Cana International |
19:55:00.000 |
21:18:00.000 |
Sheremetyevo International |
14:50:00.000 |
15:35:00.000 |
RU566 |
AirBridgeCargo |
74Y |
--- |
Frankfurt am Main |
04:45:00.000 |
--- |
Sheremetyevo International |
11:00:00.000 |
--- |
RU498 |
AirBridgeCargo |
74N |
--- |
Shanghai Pudong International |
05:00:00.000 |
--- |
Sheremetyevo International |
10:45:00.000 |
--- |
SU233 |
Aeroflot |
332 |
--- |
Indira Gandhi International |
05:05:00.000 |
05:26:00.000 |
Sheremetyevo International |
10:10:00.000 |
10:13:00.000 |
RU506 |
AirBridgeCargo |
74N |
--- |
Milano Malpensa |
05:30:00.000 |
--- |
Sheremetyevo International |
12:00:00.000 |
--- |
SU1827 |
Aeroflot |
320 |
VQ-BAZ |
Simferopol |
06:00:00.000 |
06:25:00.000 |
Sheremetyevo International |
10:15:00.000 |
10:40:00.000 |
SU2437 |
Aeroflot |
320 |
VP-BLH |
Dusseldorf International |
06:05:00.000 |
06:27:00.000 |
Sheremetyevo International |
12:25:00.000 |
12:24:00.000 |
RU440 |
AirBridgeCargo |
74N |
VP-BIM |
Hong Kong International |
06:15:00.000 |
06:15:00.000 |
Sheremetyevo International |
12:25:00.000 |
--- |
KE529 |
Korean Air Lines |
74Y |
HL7466 |
Incheon International |
06:25:00.000 |
07:07:00.000 |
Sheremetyevo International |
10:40:00.000 |
--- |
JU650 |
Jat Airways |
733 |
--- |
Belgrad Nikola Tesla |
06:45:00.000 |
06:45:00.000 |
Sheremetyevo International |
12:35:00.000 |
12:39:00.000 |
PS561 |
UIA |
73N |
UR-GAP |
Kiev/Kyiv — Borispol |
07:00:00.000 |
07:00:00.000 |
Sheremetyevo International |
10:35:00.000 |
10:35:00.000 |
SU1009 |
Aeroflot |
321 |
VQ-BED |
Kaliningrad |
07:10:00.000 |
07:36:00.000 |
Sheremetyevo International |
10:00:00.000 |
10:26:00.000 |
AF1644 |
Air France |
319 |
F-GRHL |
Charles de Gaulle |
07:15:00.000 |
07:13:00.000 |
Sheremetyevo International |
13:55:00.000 |
13:52:00.000 |
SU1867 |
Aeroflot |
320 |
VP-BQP |
Zvartnots International |
08:10:00.000 |
08:21:00.000 |
Sheremetyevo International |
11:00:00.000 |
11:11:00.000 |
5N502 |
Nordavia Regional Airlines |
735 |
--- |
Syktyvkar |
08:20:00.000 |
08:27:00.000 |
Sheremetyevo International |
10:15:00.000 |
10:11:00.000 |
KC893 |
Air Astana |
320 |
P4-KBC |
Astana |
08:40:00.000 |
08:36:00.000 |
Sheremetyevo International |
10:20:00.000 |
10:49:00.000 |
SU3 |
Aeroflot |
321 |
VP-BWO |
Pulkovo |
08:55:00.000 |
09:04:00.000 |
Sheremetyevo International |
10:20:00.000 |
10:29:00.000 |
SU1513 |
Aeroflot |
319 |
VP-BWA |
Surgut |
09:00:00.000 |
08:59:00.000 |
Sheremetyevo International |
10:35:00.000 |
10:34:00.000 |
SU1293 |
Aeroflot |
320 |
VQ-BIV |
Kazan |
09:00:00.000 |
09:27:00.000 |
Sheremetyevo International |
10:30:00.000 |
10:50:00.000 |
SU1229 |
Aeroflot |
320 |
VP-BDK |
Nizhniy Novgorod |
09:05:00.000 |
09:21:00.000 |
Sheremetyevo International |
10:25:00.000 |
10:41:00.000 |
SU1309 |
Aeroflot |
319 |
VP-BDO |
Samara |
09:15:00.000 |
09:20:00.000 |
Sheremetyevo International |
10:55:00.000 |
11:00:00.000 |
AY153 |
Finnair |
319 |
OH-LVI |
Helsinki-Vantaa |
09:25:00.000 |
09:29:00.000 |
Sheremetyevo International |
13:05:00.000 |
12:57:00.000 |
OK892 |
CSA |
319 |
--- |
Vaclav Havel Prague |
09:30:00.000 |
09:31:00.000 |
Sheremetyevo International |
15:10:00.000 |
15:05:00.000 |
SU2005 |
Aeroflot |
320 |
VP-BWI |
J. Paul II International Krakow-Balice |
09:35:00.000 |
09:56:00.000 |
Sheremetyevo International |
14:40:00.000 |
14:49:00.000 |
SU1121 |
Aeroflot |
320 |
VP-BTI |
Adler/Sochi |
09:50:00.000 |
09:55:00.000 |
Sheremetyevo International |
12:20:00.000 |
12:25:00.000 |
SU2685 |
Aeroflot |
320 |
VQ-BCM |
Schoenefeld |
09:50:00.000 |
10:44:00.000 |
Sheremetyevo International |
15:25:00.000 |
16:15:00.000 |
SU5 |
Aeroflot |
320 |
VQ-BAX |
Pulkovo |
09:55:00.000 |
10:20:00.000 |
Sheremetyevo International |
11:15:00.000 |
11:40:00.000 |
SU1839 |
Aeroflot |
SU9 |
RA-89010 |
Kharkov |
09:55:00.000 |
10:10:00.000 |
Sheremetyevo International |
13:30:00.000 |
13:20:00.000 |
SU2321 |
Aeroflot |
320 |
VQ-BHL |
Franz Josef Strauss |
10:00:00.000 |
10:16:00.000 |
Sheremetyevo International |
16:00:00.000 |
16:16:00.000 |
SU1001 |
Aeroflot |
320 |
VP-BLL |
Kaliningrad |
10:05:00.000 |
10:25:00.000 |
Sheremetyevo International |
12:55:00.000 |
13:15:00.000 |
R25807 |
Orenair |
738 |
--- |
Barnaul |
10:10:00.000 |
10:15:00.000 |
Sheremetyevo International |
11:30:00.000 |
11:35:00.000 |
SU1307 |
Aeroflot |
320 |
VP-BKX |
Tolmachevo |
10:15:00.000 |
10:19:00.000 |
Sheremetyevo International |
11:25:00.000 |
11:29:00.000 |
SU1701 |
Aeroflot |
333 |
VQ-BNS |
Vladivostok International |
10:20:00.000 |
10:24:00.000 |
Sheremetyevo International |
12:25:00.000 |
12:29:00.000 |
SU1805 |
Aeroflot |
321 |
VP-BOE |
Kiev/Kyiv — Borispol |
10:20:00.000 |
11:00:00.000 |
Sheremetyevo International |
13:50:00.000 |
14:30:00.000 |
SU2137 |
Aeroflot |
321 |
VQ-BHK |
Istanbul Ataturk |
10:20:00.000 |
11:03:00.000 |
Sheremetyevo International |
15:15:00.000 |
15:26:00.000 |
SK734 |
SAS |
320 |
OY-KAP |
Copenhagen |
10:20:00.000 |
10:46:00.000 |
Sheremetyevo International |
15:45:00.000 |
16:02:00.000 |
SU7 |
Aeroflot |
320 |
--- |
Pulkovo |
10:25:00.000 |
10:43:00.000 |
Sheremetyevo International |
11:45:00.000 |
12:03:00.000 |
SU1813 |
Aeroflot |
320 |
VP-BRX |
Donetsk |
10:30:00.000 |
10:31:00.000 |
Sheremetyevo International |
14:25:00.000 |
14:26:00.000 |
SU1831 |
Aeroflot |
320 |
--- |
Minsk International 2 |
10:50:00.000 |
11:40:00.000 |
Sheremetyevo International |
13:15:00.000 |
14:05:00.000 |
SU2107 |
Aeroflot |
320 |
VP-BZS |
Tallinn |
10:50:00.000 |
10:54:00.000 |
Sheremetyevo International |
14:30:00.000 |
14:18:00.000 |
SU1479 |
Aeroflot |
319 |
VP-BDM |
Abakan |
10:55:00.000 |
10:55:00.000 |
Sheremetyevo International |
11:55:00.000 |
11:55:00.000 |
SU1483 |
Aeroflot |
77W |
VP-BGB |
Krasnojarsk |
11:00:00.000 |
11:13:00.000 |
Sheremetyevo International |
11:35:00.000 |
11:48:00.000 |
SU2683 |
Aeroflot |
319 |
VQ-BCO |
Riga |
11:00:00.000 |
11:24:00.000 |
Sheremetyevo International |
14:35:00.000 |
14:44:00.000 |
D95399 |
Donavia |
319 |
VP-BNN |
Stavropol |
11:15:00.000 |
11:17:00.000 |
Sheremetyevo International |
13:30:00.000 |
13:32:00.000 |
SU2035 |
Aeroflot |
SU9 |
RA-89008 |
Otopeni International |
11:15:00.000 |
11:28:00.000 |
Sheremetyevo International |
15:35:00.000 |
15:33:00.000 |
SU11 |
Aeroflot |
320 |
--- |
Pulkovo |
11:30:00.000 |
11:49:00.000 |
Sheremetyevo International |
12:45:00.000 |
13:04:00.000 |
SU1139 |
Aeroflot |
321 |
VQ-BKU |
Adler/Sochi |
11:35:00.000 |
11:55:00.000 |
Sheremetyevo International |
14:00:00.000 |
14:20:00.000 |
SU1211 |
Aeroflot |
320 |
VQ-BIT |
Samara |
11:40:00.000 |
12:13:00.000 |
Sheremetyevo International |
13:25:00.000 |
13:42:00.000 |
SU1759 |
Aeroflot |
SU9 |
VP-BZQ |
Volgograd |
11:45:00.000 |
11:53:00.000 |
Sheremetyevo International |
13:35:00.000 |
13:43:00.000 |
SU1255 |
Aeroflot |
319 |
VP-BDN |
Begishevo |
11:50:00.000 |
12:03:00.000 |
Sheremetyevo International |
13:40:00.000 |
13:53:00.000 |
SU1643 |
Aeroflot |
320 |
VQ-BIW |
Astrakhan |
11:50:00.000 |
11:55:00.000 |
Sheremetyevo International |
14:10:00.000 |
14:15:00.000 |
SU1305 |
Aeroflot |
320 |
VP-BLP |
Mineralnye Vody |
11:50:00.000 |
12:08:00.000 |
Sheremetyevo International |
14:15:00.000 |
14:33:00.000 |
SU1761 |
Aeroflot |
738 |
VP-BRH |
Chita |
11:55:00.000 |
12:10:00.000 |
Sheremetyevo International |
12:45:00.000 |
13:00:00.000 |
SU1221 |
Aeroflot |
320 |
VP-BMF |
Nizhniy Novgorod |
12:05:00.000 |
12:12:00.000 |
Sheremetyevo International |
13:10:00.000 |
13:17:00.000 |
SU1743 |
Aeroflot |
333 |
VQ-BQX |
Yuzhno-Sakhalinsk |
12:10:00.000 |
12:20:00.000 |
Sheremetyevo International |
14:05:00.000 |
14:15:00.000 |
D95301 |
Donavia |
734 |
VQ-BCS |
Rostov |
12:15:00.000 |
12:28:00.000 |
Sheremetyevo International |
14:15:00.000 |
14:28:00.000 |
SU13 |
Aeroflot |
319 |
--- |
Pulkovo |
12:20:00.000 |
12:50:00.000 |
Sheremetyevo International |
13:35:00.000 |
14:05:00.000 |
5N117 |
Nordavia Regional Airlines |
735 |
--- |
Arkhangelsk |
12:20:00.000 |
12:25:00.000 |
Sheremetyevo International |
14:05:00.000 |
14:10:00.000 |
SU1191 |
Aeroflot |
320 |
VQ-BEA |
Kazan |
12:25:00.000 |
13:04:00.000 |
Sheremetyevo International |
13:55:00.000 |
14:34:00.000 |
SU1751 |
Aeroflot |
738 |
VP-BRF |
Yakutsk |
12:30:00.000 |
12:58:00.000 |
Sheremetyevo International |
13:15:00.000 |
13:43:00.000 |
SU1547 |
Aeroflot |
SU9 |
--- |
Anapa |
12:30:00.000 |
12:50:00.000 |
Sheremetyevo International |
14:45:00.000 |
15:05:00.000 |
D95377 |
Donavia |
319 |
--- |
Mineralnye Vody |
12:45:00.000 |
13:03:00.000 |
Sheremetyevo International |
15:10:00.000 |
15:28:00.000 |
D95363 |
Donavia |
319 |
VP-BQK |
Rostov |
13:05:00.000 |
13:20:00.000 |
Sheremetyevo International |
15:05:00.000 |
15:20:00.000 |
SU1411 |
Aeroflot |
321 |
VQ-BOI |
Koltsovo International |
13:15:00.000 |
13:43:00.000 |
Sheremetyevo International |
13:40:00.000 |
14:08:00.000 |
SU1731 |
Aeroflot |
333 |
VQ-BCQ |
Petropavlovsk-Kamchatsky |
13:30:00.000 |
13:44:00.000 |
Sheremetyevo International |
14:30:00.000 |
14:44:00.000 |
SU15 |
Aeroflot |
320 |
--- |
Pulkovo |
13:30:00.000 |
13:39:00.000 |
Sheremetyevo International |
14:45:00.000 |
14:52:00.000 |
SU1231 |
Aeroflot |
320 |
VP-BLR |
Ufa |
13:55:00.000 |
14:19:00.000 |
Sheremetyevo International |
14:00:00.000 |
14:24:00.000 |
SU1421 |
Aeroflot |
320 |
VP-BNL |
Chelyabinsk |
13:55:00.000 |
13:56:00.000 |
Sheremetyevo International |
14:20:00.000 |
14:21:00.000 |
R25803 |
Orenair |
738 |
--- |
Irkutsk |
14:05:00.000 |
14:30:00.000 |
Sheremetyevo International |
14:50:00.000 |
15:15:00.000 |
SU1201 |
Aeroflot |
SU9 |
--- |
Perm |
14:10:00.000 |
--- |
Sheremetyevo International |
14:25:00.000 |
14:25:00.000 |
5N9134 |
Nordavia Regional Airlines |
--- |
--- |
Kazan |
14:10:00.000 |
15:07:00.000 |
Sheremetyevo International |
15:30:00.000 |
--- |
SU17 |
Aeroflot |
320 |
--- |
Pulkovo |
14:25:00.000 |
14:56:00.000 |
Sheremetyevo International |
15:40:00.000 |
16:11:00.000 |
Future work
- Хочу сделать более красивый вид таблицы результатами
- Нормальный вывод в PDF, а не как печать web-страницы
- Приложение для Android
This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers.