从HTML中提取脚本标记中的字符串

2024-09-29 00:12:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试制作一个web scraper,以便从以下网站获取数据(稍后我将为同一网站上的多家航空公司执行此操作): https://www.flightradar24.com/data/airlines/kl-klm/routes

我目前拥有以下代码:

from bs4 import BeautifulSoup
import requests

airlines = ['kl-klm']

for a in airlines:
    url = 'https://www.flightradar24.com/data/airlines/' + a + '/routes'
    page = requests.get(url)
    soup = BeautifulSoup(page.text, 'html.parser')
    print(soup)

这给了我整个页面的源代码,但我想在脚本标记中提取一个特定的文本块,这是

var arrRoutes=[{"airport1":{"country":"Denmark","iata":"AAL","icao":"EKYT","lat":57.092781,"lon":9.849164,"name":"Aalborg Airport"},"airport2":{"country":"Netherlands","iata":"AMS","icao":"EHAM","lat":52.308609,"lon":4.763889,"name":"Amsterdam Schiphol Airport"}},{"airport1":{"country":"United Kingdom","iata":"ABZ","icao":"EGPD","lat":57.201939,"lon":-2.19777,"name":"Aberdeen International Airport"},"airport2":{"country":"Netherlands","iata":"AMS","icao":"EHAM","lat":52.308609,"lon":4.763889,"name":"Amsterdam Schiphol Airport"}}...

…一直到名单的最后。你知道吗

我怎样才能提取出这样的方式,我可以找到每个机场的进出港航班总数?例如,阿姆斯特丹史基浦机场显示为机场1或2的总次数?你知道吗

有没有办法先从HTML中提取字符串,然后用字典将其转换成Python列表?或者直接计算字符串中的每个元素更有意义?你知道吗


Tags: namehttpscomdata网站wwwcountrylon
2条回答

使用re.compile

例如:

import re

soup = BeautifulSoup(page.text, 'html.parser')
jData = soup.find("script", text=re.compile(r"var arrRoutes=.*?")).string
print( jData.replace("var arrRoutes=", ""))

输出:

[{"airport1":{"country":"Denmark","iata":"AAL","icao":"EKYT","lat":57.092781,"lon":9.849164,"name":"Aalborg Airport"},"airport2":{"country":"Netherlands","iata":"AMS","icao":"EHAM","lat":52.308609,"lon":4.763889,"name":"Amsterdam Schiphol Airport"}},{"airport1":{"country":"United Kingdom","iata":"ABZ","icao":"EGPD","lat":57.201939,"lon":-2.19777,"name":"Aberdeen International Airport"},"airport2":{"country":"Netherlands","iata":"AMS","icao":"EHAM","lat":52.308609,"lon":4.763889,"name":"Amsterdam Schiphol Airport"}},......

可以使用ast.literal_eval将数据提取到python列表中。我做了一个简单的函数find_airport(),在这里提供数据和机场名称,并返回它在机场1和机场2的次数:

from bs4 import BeautifulSoup
import requests
import re
from ast import literal_eval
from pprint import pprint

airlines = ['kl-klm']

headers = {"Host":"www.flightradar24.com",
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding":"gzip,deflate,br",
"User-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36"}

def find_aiport(data, name):
    airport_1, airport_2 = 0, 0
    for d in data:
        if d['airport1']['name'] == name:
            airport_1 += 1
        if d['airport2']['name'] == name:
            airport_2 += 1
    return airport_1, airport_2

for a in airlines:
    url = 'https://www.flightradar24.com/data/airlines/' + a + '/routes'
    page = requests.get(url, headers=headers)
    soup = BeautifulSoup(page.text, 'lxml')

    m = re.search(r'(?<=arrRoutes=)\[\{(.*?)\}\]', soup.text)
    l = literal_eval(m[0])
    pprint(l)

    print(find_aiport(l, 'Amsterdam Schiphol Airport'))

印刷品:

[{'airport1': {'country': 'Denmark',
               'iata': 'AAL',
               'icao': 'EKYT',
               'lat': 57.092781,
               'lon': 9.849164,
               'name': 'Aalborg Airport'},
  'airport2': {'country': 'Netherlands',
               'iata': 'AMS',
               'icao': 'EHAM',
               'lat': 52.308609,
               'lon': 4.763889,
               'name': 'Amsterdam Schiphol Airport'}},
 {'airport1': {'country': 'United Kingdom',
               'iata': 'ABZ',
               'icao': 'EGPD',
               'lat': 57.201939,
               'lon': -2.19777,
               'name': 'Aberdeen International Airport'},
  'airport2': {'country': 'Netherlands',
               'iata': 'AMS',
               'icao': 'EHAM',
               'lat': 52.308609,
               'lon': 4.763889,
               'name': 'Amsterdam Schiphol Airport'}},

...and so on

最后:

(147, 146)

阿姆斯特丹史基浦机场

相关问题 更多 >