Очистка данных из таблиц в зависимости от интерактивной карты
Еще один скребущий вопрос. Я пытаюсь собрать данные со следующего веб-сайта: https://www.flightradar24.com/data/airlines/kl-klm/routes
Однако данные, которые я хочу получить, отображаются только после нажатия на один из аэропортов в виде таблицы под картой. Из этой таблицы я хочу извлечь число, указывающее частоту ежедневных рейсов в каждый аэропорт. Например, если вы нажмете на Париж Шарль де Голль и осмотрите страну Нидерланды из таблицы, в строке выше будет показано td rowspan="6", что в данном случае означает, что KLM выполняет 6 рейсов в день в Париж.
Я предполагаю, что мне нужно будет использовать сеанс браузера, например, Selenium или что-то подобное, поэтому я начал со следующего кода, но я не уверен, куда идти дальше, так как не могу найти точки аэропорта в исходный код.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.binary_location = 'C:/Users/C55480/AppData/Local/Google/Chrome SxS/Application/chrome.exe'
driver = webdriver.Chrome(executable_path='C:/Users/C55480/.spyder-py3/going_headless/chromedriver.exe', chrome_options=chrome_options)
airlines = ['kl-klm', 'dy-nax', 'lh-dlh']
for a in airlines:
url = 'https://www.flightradar24.com/data/airlines/' + a + '/routes'
page = driver.get(url)
Есть ли способ заставить Selenium щелкнуть по каждой точке и определить количество ежедневных рейсов для каждого аэропорта, а затем найти общее количество ежедневных рейсов в каждую страну?
3 ответа
Вместо того, чтобы использовать Selenium, попробуйте получить необходимые данные с помощью прямых HTTP-запросов:
import requests
import json
s = requests.session()
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0"}
r = s.get("https://www.flightradar24.com/data/airlines/kl-klm/routes", headers=headers)
Данные для каждого аэропорта можно найти в скрипте узла, который выглядит как
<script>var arrRoutes=[{"airport1":{"country":"Denmark","iata":"AAL","icao":"EKYT","lat":57.092781,"lon":9.849164,"name":"Aalborg Airport"}...]</script>
Чтобы получить JSON от arrRoutes
переменная:
my_json = json.loads(r.text.split("arrRoutes=")[-1].split(", arrDates=")[0])
Вам необходимо получить сокращение (значение для "iata"
ключ) для каждого аэропорта:
abbs_list = []
for route in my_json:
if route["airport1"]["country"] == "Netherlands":
abbs_list.append(route["airport2"]["iata"])
Выход из print(abbs_list)
должно быть как ['AAL', 'ABZ'...]
Теперь мы можем запросить данные для каждого аэропорта:
url = "https://www.flightradar24.com/data/airlines/kl-klm/routes?get-airport-arr-dep={}"
for abbr in abbs_list:
cookie = r.cookies.get_dict()
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0",
"Content-Type": "application/json",
"x-fetch": "true"}
response = s.get(url.format(abbr), cookies=cookie, headers=headers).json()
print(abbr, ": ", response["arrivals"]["Netherlands"]["number"]["flights"])
Карта не представлена в HTML/CSS, поэтому я не думаю, что с ней можно взаимодействовать через Selenium.
Однако я наткнулся на API Sikuli, который позволяет распознаванию изображений взаимодействовать с Картами Google (как на странице, на которую вы ссылаетесь), капчами... Вы можете обрезать этот маркер и попытаться использовать Sikuli для его распознавания и щелкнуть по нему. См. http://www.assertselenium.com/maven/sikuliwebdriver-2/ для небольшого примера того, как его использовать.
Однако данные в таблицах можно легко выбрать с помощью Xpath и проанализировать с помощью такого инструмента, как Selenium. Однако кажется, что Sikuli можно использовать только в Java, поэтому вам придется использовать Selenium и Java.
Вы можете использовать Kantu Selenium IDE, он может делать следующее:
Визуально найдите маркер, используя поиск изображений
Нажмите на маркер, используя Click #efp <= это работает внутри холста
Веб-очистка таблицы с использованием xpath и классических команд Selenium IDE, таких как storeText
Проблема, которую вам еще нужно решить, состоит в том, как щелкнуть все точки (аэропорты) на карте. Это та же проблема, что и у вас, если вы будете использовать Sikuli.
Обновление: на самом деле, я думаю, что вы можете решить эту проблему, не используя распознавание изображений, а "тупо", используя ClickAt, чтобы кликать в любой точке карты (возможно, каждый третий пиксель или около того). Тогда, по мировоззрению, у вас будут все аэропорты.