在Python中查找跑酷艺术家可以到达的最远建筑的程序

在Python中查找跑酷艺术家可以到达的最远建筑的程序

跑酷艺术家需要在城市中寻找最高、最有挑战性的建筑,来展示自己极限的能力。本文将介绍如何使用Python来写一个程序,以找到跑酷艺术家可以到达的最远建筑。

需要用到的Python库

在编写这个程序之前,我们需要使用Python中的一些库。具体来说,我们需要使用 requests、geopy、folium和beautifulsoup4 库。

  1. requests库: 用于向网站发送请求。
  2. geopy库: 用于获取城市名称和城市的纬度和经度。
  3. folium库: 用于展示生成的地图,并用不同的图标标记不同的建筑物和位置。
  4. beautifulsoup4库: 用于解析谷歌地图网站并获取所需的坐标信息。

如果你还没有安装这些库,请先安装它们。你可以使用以下命令安装它们:

pip install requests
pip install geopy
pip install folium
pip install beautifulsoup4

程序实现

以下是Python程序的完整代码,实现了功能:输入城市名称,根据该城市生成一个地图,并标记跑酷艺术家可以到达的最远建筑物:

import requests
from bs4 import BeautifulSoup
from geopy.geocoders import Nominatim
import folium

def main():
    # 首先,需要获取指定城市的经纬度
    location = get_location()
    print("已获取到城市所在经纬度!")

    # 加载谷歌地图,可视化该城市
    # 使用 location[0] 和 location[1] 获取城市所在经度和纬度
    city_map = folium.Map(location=[location[0], location[1]], zoom_start=14)
    print("已加载地图!")

    # 获取所有的建筑物在地图上的位置,并绘制图标
    buildings_location = []
    farthest_building = None
    farthest_distance = 0
    for building in get_buildings_list(location):
        # 使用 get_distance 方法获取跑酷艺术家到该建筑物的距离
        distance = get_distance(location[0], location[1], building[1], building[2])

        # 如果该建筑物是跑酷艺术家可以到达的最远建筑
        if distance > farthest_distance:
            farthest_building = building[0]
            farthest_distance = distance

        # 将建筑物添加到地图上
        folium.Marker(
            location=[building[1], building[2]],
            popup=building[0],
            icon=folium.Icon(icon='building')
        ).add_to(city_map)

        # 添加位置到列表中
        buildings_location.append([building[1], building[2]])

    # 在地图上标记跑酷艺术家可以到达的最远建筑
    folium.Marker(
        location=buildings_location[farthest_building],
        popup="跑酷艺术家可以到达的最远建筑",
        icon=folium.Icon(icon='star')
    ).add_to(city_map)

    # 将地图保存为 HTML 文件并用浏览器打开
    city_map.save("city_map.html")
    print("地图已生成,保存为 city_map.html 文件!已找到跑酷艺术家可以到达的最远建筑:%s" % farthest_building)

def get_location():
    # 获取城市名称
    city_name = input("请输入城市名称:")

    # 实例化 Nominatim 对象
    geolocator = Nominatim(user_agent="my-application")

    # 获取城市的位置信息(即,纬度和经度)
    location = geolocator.geocode(city_name,timeout=10)

    if location is None:
        print("无法找到该城市,请检查输入或更换城市重新尝试!")
        # 退出程序
        exit()

    return (location.latitude, location.longitude)

def get_buildings_list(location):
    # 生成谷歌地图的 URL
    url = f"https://www.google.com/maps/search/buildings/@{location[0]},{location[1]},14z"

    # 发送请求获取网站内容
    r = requests.get(url)

    # 如果请求失败则退出程序
    if r.status_code != 200:
        print("请求失败,请检查您的网络连接!")
        # 退出程序
        exit()

    # 使用 BeautifulSoup 解析 HTML
    soup = BeautifulSoup(r.content, 'html.parser')

    # 获取所有的建筑物
    buildings = soup.select('div.section-result-content')

    buildings_list = []
    for building in buildings:
        # 获取建筑物名称
        name = building.find('h3').text

        # 获取建筑物位置
        location = building.find('button')['data-pid']

        position_url = f"https://www.google.com/maps/dir/?api=1&destination_place_id={location}"

        position_request = requests.get(position_url)
        position_soup = BeautifulSoup(position_request.content, 'html.parser')

        # 获取该建筑物的位置(即,纬度和经度)
        position = position_soup.find_all('script')[1].string
        start = position.find('center:') + len('center:')
        end = position.find(',', start)
        lat = float(position[start:end])
        start = end + 1
        end = position.find('}', start)
        lng = float(position[start:end])

        # 添加名称和位置信息到列表中
        buildings_list.append((name, lat, lng))

    return buildings_list

def get_distance(lat1, lng1, lat2, lng2):
    # 使用 geopy 库计算跑酷艺术家到建筑物的距离
    geolocator = Nominatim(user_agent="my-application")
    start = geolocator.reverse(f"{lat1}, {lng1}")
    end = geolocator.reverse(f"{lat2}, {lng2}")
    distance = start.distance(end)

    return distance


if __name__ == '__main__':
    main()

解析代码

以下是代码的分析和解释。

首先,我们导入必要的库:

import requests
from bs4 import BeautifulSoup
from geopy.geocoders import Nominatim
import folium
  • requests库: 用于向网站发送请求。
  • Beautifulsoup4库: 用于解析 HTML 文件。
  • geopy库: 用于获取城市和建筑物的位置和距离。
  • folium库: 用于展示生成的地图。

然后,在 main()函数中,我们需要获取城市的位置和名称,然后加载谷歌地图:

def main():
    # 首先,需要获取指定城市的经纬度
    location = get_location()
    print("已获取到城市所在经纬度!")

    # 加载谷歌地图,可视化该城市
    # 使用 location[0] 和 location[1] 获取城市所在经度和纬度
    city_map = folium.Map(location=[location[0], location[1]], zoom_start=14)
    print("已加载地图!")

获取城市位置时,我们调用 get_location()函数:

def get_location():
    # 获取城市名称
    city_name = input("请输入城市名称:")

    # 实例化 Nominatim 对象
    geolocator = Nominatim(user_agent="my-application")

    # 获取城市的位置信息(即,纬度和经度)
    location = geolocator.geocode(city_name, timeout=10)

    if location is None:
        print("无法找到该城市,请检查输入或更换城市重新尝试!")
        # 退出程序
        exit()

    return (location.latitude, location.longitude)

在 get_location() 函数中,我们使用 geopy 库来获取城市的纬度和经度。然后,我们从 Nominatim(server=uri, user_agent=user_agent, timeout=timeout, proxies=proxies) 对象中获取位置信息。如果无法找到该城市,则会退出程序。

接下来,我们需要获取建筑物列表,包括每个建筑物的名称、纬度和经度。我们的方法是使用 requests 库向谷歌地图网站发送请求:

def get_buildings_list(location):
    # 生成谷歌地图的 URL
    url = f"https://www.google.com/maps/search/buildings/@{location[0]},{location[1]},14z"

    # 发送请求获取网站内容
    r = requests.get(url)

    # 如果请求失败则退出程序
    if r.status_code != 200:
        print("请求失败,请检查您的网络连接!")
        # 退出程序
        exit()

    # 使用 BeautifulSoup 解析 HTML
    soup = BeautifulSoup(r.content, 'html.parser')

    # 获取所有的建筑物
    buildings = soup.select('div.section-result-content')

    buildings_list = []
    for building in buildings:
        # 获取建筑物名称
        name = building.find('h3').text

        # 获取建筑物位置
        location = building.find('button')['data-pid']

        position_url = f"https://www.google.com/maps/dir/?api=1&destination_place_id={location}"

        position_request = requests.get(position_url)
        position_soup = BeautifulSoup(position_request.content, 'html.parser')

        # 获取该建筑物的位置(即,纬度和经度)
        position = position_soup.find_all('script')[1].string
        start = position.find('center:') + len('center:')
        end = position.find(',', start)
        lat = float(position[start:end])
        start = end + 1
        end = position.find('}', start)
        lng = float(position[start:end])

        # 添加名称和位置信息到列表中
        buildings_list.append((name, lat, lng))

    return buildings_list

这将使用 BeautifulSoup 库解析页面信息,并获取建筑物的名称和位置。我们首先获取所有建筑物的内容,然后从每个建筑物中提取名称和位置信息。

接下来,我们使用 geopy 库计算跑酷艺术家到不同建筑物的距离:

def get_distance(lat1, lng1, lat2, lng2):
    # 使用 geopy 库计算跑酷艺术家到建筑物的距离
    geolocator = Nominatim(user_agent="my-application")
    start = geolocator.reverse(f"{lat1}, {lng1}")
    end = geolocator.reverse(f"{lat2}, {lng2}")
    distance = start.distance(end)

    return distance

最后,我们使用 folium 库来展示生成的地图:

# 将地图保存为 HTML 文件并用浏览器打开
city_map.save("city_map.html")
print("地图已生成,保存为 city_map.html 文件!已找到跑酷艺术家可以到达的最远建筑:%s" % farthest_building)

结论

本文通过使用 requests、geopy、folium和Beautifulsoup4 库,展示了如何使用Python编写一个程序,用于查找跑酷艺术家可以到达的最远建筑。这个程序将城市可视化,标记建筑物的位置,并用不同的图标标记跑酷艺术家可以到达的最远建筑。我们希望,这篇文章能够帮助你进一步掌握Python编程。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程