我正在尝试制作一个网络抓取工具,以从以下网站中获取数据(我稍后想在同一网站上为多家航空公司使用): 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列表?还是直接对字符串中的每个元素进行计数是否更有意义?
答案 0 :(得分:3)
您可以使用ast.literal_eval
将数据提取到python列表中。我做了一个简单的函数find_airport()
,其中提供了数据和机场名称,并返回它在airport_1和airport_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)
“阿姆斯特丹史基浦机场”
答案 1 :(得分:1)
使用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"}},......