python爬取城市公交线路及公交站点坐标

       现实工作中可能会碰到分析城市交通等方面的需求,这就不仅仅需要获取公交线路和站点的字段属性,更重要的是获取经纬度,便于arcgis上图。所以今天这篇文章就来讲讲怎么获取一个城市的所有的公交线路、公交站点、经纬度信息以及如何生成arcgis中的shp文件。首先明确以下几个问题:

  1. 选取公交信息网站——8684网站
  2. 获取经纬度——通过调用高德地图API
  3. 坐标转换——高德坐标系(又称火星坐标系) to WGS84/国家大地2000 

 一、解析8684网站网页信息

       可以查询公交信息的网站其实也挺多的,像8684、公交查询网、坐车网等等,这里我就用8684了(看起来顺眼一点hhhhhh)。打开8684网站,定义城市(这里默认武汉市),选择【公交】→【线路查询】→【线路分类】,可以看到武汉市有很多类型的线路,先选择一个汉阳线路,可以看到下面有很多路线的公交。

       老规矩,打开开发人员工具,发现所有的公交线路都存在<div class="list clearfix">里,一个站点名称在一个<a>标签下。那接下的事情就好办了。

#导入需要的库,模块报错在setting里install一般能解决
import requests
import json
from bs4 import BeautifulSoup
url = "https://wuhan.8684.cn/line3"  # 今天就只先演示获取一种线路类型下所有公交的信息,要想拿到整个城市的,其实就加个for循环:line1,line2,line3......
# 伪装请求头
headers = {
    "user-agent": "Mozilla/5.0 (Windows
### 如何用Python爬取公交线路数据 为了实现公交线路及其站点爬取并生成地理空间文件,可以按照以下方式操作: #### 数据源的选择 通常情况下,可以选择公开的城市公共交通信息网站作为数据源。例如,在中国范围内常用的 **8684公交网** 提供了详细的公交线路站点信息[^2]。 #### 使用第三方库辅助开发 针对交通时空大数据处理需求,推荐使用 `TransBigData` 这一专门用于交通数据分析的 Python 库[^1]。此外,还需要借助其他常用库完成网络请求、HTML 解析等工作: - 请求网页内容:`requests` - HTML 解析:`BeautifulSoup` 或者 `lxml` - 地理坐标转换:可调用高德地图 API 完成火星坐标系 (GCJ-02) 到 WGS84 坐标的转换 以下是完整的解决方案框架: --- #### 实现方案 ##### 步骤说明 1. **获取目标页面结构** - 访问指定城市的公交线路列表页(如 8684 公交网)。 - 找到包含所有公交线路链接的 DOM 节点,提取每条线路的具体 URL 和名称[^4]。 2. **解析单条线路详情** - 对于每一条公交线路,访问其详细页面。 - 抽取出站点名称、经纬度以及其他附加信息(如首末班车时间等)[^3]。 3. **调用外部接口补充数据** - 如果某些字段缺失或者需要更精确的信息,则可以通过高德开放平台的关键字搜索服务补全数据。 4. **保存为 GIS 文件格式** - 将最终整理好的数据导出为 ArcGIS 支持的标准 SHP 文件形式以便后续可视化分析。 --- #### 示例代码 以下是一个基于上述逻辑编写的简化版本脚本: ```python import requests from bs4 import BeautifulSoup import pandas as pd import geopandas as gpd from shapely.geometry import Point, LineString def fetch_bus_lines(city_url): """抓取某市全部公交线路""" response = requests.get(city_url) soup = BeautifulSoup(response.text, 'html.parser') bus_list_div = soup.find('div', class_='list clearfix') # 寻找公交线路容器节点 lines = [] for a_tag in bus_list_div.find_all('a'): line_name = a_tag.text.strip() href = a_tag['href'] lines.append({'name': line_name, 'url': f"http://www.8684.cn{href}"}) return lines def parse_line_details(line_url): """解析单一公交线路细节""" resp = requests.get(line_url) soup = BeautifulSoup(resp.text, 'html.parser') stations_data = [] # 存储各站基本信息 station_table = soup.select_one('.bus_site_list table tbody tr td span.wbfspan') # 自定义选择器匹配站点区域 if not station_table: raise ValueError(f"No valid data found at {line_url}") for idx, stn_info in enumerate(station_table.strings): name = str(stn_info).strip() or None # 取得对应位置上的经维度值(假设已知存在固定样式class="gps") gps_elm = next((el for el in stn_info.parent.next_siblings if getattr(el,'attrs',{'':''}).get('class')==["gps"]),None) latlng_str = gps_elm and re.findall(r'\d+\.\d+',str(gps_elm))[:2] or ['NaN']*2 lng,lat=map(float,latlng_str) stations_data.append({ "order":idx+1, "stationName":name , "longitude":lng,"latitude":lat }) return {"stations":stations_data} if __name__ == "__main__": city_page_link='http://www.example.com/city-buses' # 替换为目标城市首页地址 all_buses = fetch_bus_lines(city_page_link) full_results=[] for buselem in all_buses[:5]: # 测试前五条记录即可 try: resdict=parse_line_details(buselem['url']) resdict.update({"routeTitle":buselem['name']}) full_results.extend(resdict['stations']) except Exception as e: print(e) continue df_stations=pd.DataFrame(full_results)[['routeTitle','order','stationName','longitude','latitude']] geo_df=gpd.GeoDataFrame(df_stations.copy(),geometry=[Point(xy)for xy in zip(df_stations.longitude,df_stations.latitude)]) output_shp_path='./output/bus_routes.shp' geo_df.to_file(output_shp_path,index=False,driver='ESRI Shapefile') ``` --- #### 注意事项 - 上述代码仅为演示目的编写,实际应用时需考虑异常情况下的鲁棒性设计。 - 高频率访问可能触发反爬机制,请适当加入延时策略或配置代理池规避风险。 ---
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值