Readme

usage:

async function example() { await @nini1294.flightRadar24( "bf721", "01 Jan 2023", "America/Los_Angeles" ); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// import { persistence } from "https://esm.town/v/raylu/persistence";
import { fetch } from "https://esm.town/v/std/fetch";
// import { get } from "https://esm.town/v/std/get";
import { set } from "https://esm.town/v/std/set";
import process from "node:process";
export const flightRadar24 = async (
flightNumber,
utcDepartureDate,
outputTZ,
) => {
const parseHTML = async (url) => {
const { DOMParser } = await import(
"https://deno.land/x/deno_dom/deno-dom-wasm.ts"
);
const response = await fetch(url);
const html = await response.text();
return new DOMParser().parseFromString(html, "text/html");
};
const dateFormatter = Intl.DateTimeFormat("en", {
timeZone: outputTZ,
dateStyle: "medium",
});
const timeFormatter = Intl.DateTimeFormat("en", {
timeZone: outputTZ,
hour12: false,
timeStyle: "short",
});
const formatTime = (td) => {
const ts = td.getAttribute("data-timestamp");
if (ts === "")
return "-";
return timeFormatter.format(new Date(Number(ts + "000")));
};
const cloneSansStatus = (flight) => {
const { "status": _, ...flightSansStatus } = flight;
return flightSansStatus;
};
const flightsDifferent = (oldFlights, newFlights) => {
if (oldFlights === undefined)
return true;
const oldSansStatus = oldFlights.map(cloneSansStatus);
const newSansStatus = newFlights.map(cloneSansStatus);
return JSON.stringify(oldSansStatus) !== JSON.stringify(newSansStatus);
};
const flightDOM = await parseHTML(
"https://www.flightradar24.com/data/flights/" + flightNumber,
);
const flightTable = flightDOM.body.querySelector("table#tbl-datatable");
console.log(flightDOM.body);
let row = null;
for (const tr of flightTable.querySelectorAll("tr.data-row")) {
const date = tr.querySelector("td[data-time-format]").textContent.trim();
if (date === utcDepartureDate) {
row = tr;
break;
}
}
if (row === null) {
console.log("no flight on date");
return;
}
const aircraft = row.children[5];
const link = aircraft.querySelector("a");
if (link === null) {
console.log("no registration");
return;
}
const aircraftURL = "https://www.flightradar24.com"
+ link.getAttribute("href");
const aircraftDOM = await parseHTML(aircraftURL);
const aircraftTable = aircraftDOM.body.querySelector("table#tbl-datatable");
let foundFlight = false;
const flights = [];
for (const tr of aircraftTable.querySelectorAll("tr.data-row")) {
const rowFlightNumber = tr.querySelector("a[target=_self]").textContent;
if (!foundFlight && rowFlightNumber.toLowerCase() === flightNumber) {
foundFlight = true;
}
if (foundFlight) {
const dateTs = Number(
tr.querySelector("td[data-time-format]").getAttribute(
"data-timestamp",
) + "000",
);
const date = dateFormatter.format(new Date(dateTs));
const from = tr.children[3].textContent.trim();
const to = tr.children[4].textContent.trim();
const schedDeparture = formatTime(tr.children[7]);
const schedArrival = formatTime(tr.children[9]);
const actualDeparture = formatTime(tr.children[8]);
const statusPrefix = tr.children[11].getAttribute("data-prefix");
const status = statusPrefix + formatTime(tr.children[11]);
flights.push({
"flightNumber": rowFlightNumber,
from,
to,
date,
schedDeparture,
schedArrival,
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
August 29, 2024