Python 爬虫:抓取城市公共交通数据(公交、地铁等)
了解实时公交、地铁信息,不仅能帮助市民规划出行,还能为交通部门提供优化线路、调整车次等数据支持。本文将带您逐步学习如何通过 Python 爬虫抓取城市公共交通数据,并进行分析和可视化。我们可以将抓取的公交、地铁信息存入 SQLite 数据库,并进行进一步的数据分析。数据存储之前,我们需要清洗一下数据,例如去除无效数据、转换数据格式等。为了确保数据的实时性,我们可以设置定时任务,定期抓取公共交通数据
1. 引言
1.1 为什么要抓取公共交通数据?
随着城市化进程的加快,公共交通系统已经成为大多数城市居民出行的主要方式。了解实时公交、地铁信息,不仅能帮助市民规划出行,还能为交通部门提供优化线路、调整车次等数据支持。
通过爬虫技术,我们可以轻松地抓取城市的公共交通数据,例如:
- 公交线路信息:各条线路的站点、首末班车时间、运行时刻等。
- 地铁信息:地铁线路、换乘站、运营时间、票价等。
- 实时交通信息:公交、地铁实时到达时间、故障信息、拥挤度等。
本文将带您逐步学习如何通过 Python 爬虫抓取城市公共交通数据,并进行分析和可视化。
2. 环境准备
2.1 安装必要的库
在本教程中,我们将使用以下库来完成数据抓取、存储和分析任务:
bash
复制编辑
pip install requests beautifulsoup4 selenium pandas sqlite3 matplotlib seaborn
- requests:用于发送 HTTP 请求,获取网页内容。
- BeautifulSoup:用于解析 HTML 页面,提取所需的数据。
- Selenium:用于处理动态加载的网页。
- pandas:用于存储和操作数据。
- matplotlib 和 seaborn:用于数据可视化。
2.2 导入相关库
python
复制编辑
import requests
from bs4 import BeautifulSoup
import pandas as pd
import sqlite3
import matplotlib.pyplot as plt
import seaborn as sns
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
2.3 配置 Selenium
部分公共交通网站可能采用了 JavaScript 渲染页面内容,使用 requests
库无法直接抓取。这时,我们可以使用 Selenium 模拟浏览器行为,获取页面的动态内容。
python
复制编辑
# 配置 Chrome 浏览器驱动(确保已安装 chromedriver)
options = webdriver.ChromeOptions()
options.add_argument("--headless") # 无界面模式
driver = webdriver.Chrome(options=options)
3. 爬取公交信息
3.1 目标网站分析
我们以 某城市公交网站 为例,该网站提供了所有公交线路的详细信息。页面包含以下内容:
- 公交线路名称
- 站点信息
- 首末班车时间
- 票价等信息
3.2 发送 HTTP 请求
首先,我们通过 requests
库向目标网站发送请求,获取网页内容。
python
复制编辑
def fetch_page(url):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.text
else:
print(f"请求失败,状态码:{response.status_code}")
return None
3.3 解析公交数据
假设网页上每条公交线路的信息都包含在 <div class="bus-line">
标签内,我们可以使用 BeautifulSoup 进行解析。
python
复制编辑
def parse_bus_data(html):
soup = BeautifulSoup(html, "html.parser")
buses = []
for bus in soup.find_all("div", class_="bus-line"):
line_name = bus.find("h3", class_="line-name").text.strip()
stations = [station.text.strip() for station in bus.find_all("span", class_="station")]
start_time = bus.find("span", class_="start-time").text.strip()
end_time = bus.find("span", class_="end-time").text.strip()
fare = bus.find("span", class_="fare").text.strip()
buses.append({
"line_name": line_name,
"stations": stations,
"start_time": start_time,
"end_time": end_time,
"fare": fare
})
return buses
3.4 抓取多个页面数据
如果公交信息分布在多个页面,我们可以通过分页抓取所有数据。
python
复制编辑
def fetch_all_buses(url, pages=5):
all_buses = []
for page in range(1, pages + 1):
page_url = f"{url}?page={page}"
html = fetch_page(page_url)
if html:
buses = parse_bus_data(html)
all_buses.extend(buses)
return all_buses
3.5 示例:抓取公交信息
python
复制编辑
url = "https://city-bus-info.com/routes" # 假设的公交路线信息网站
buses = fetch_all_buses(url, pages=3)
# 打印前5条抓取的公交信息
for bus in buses[:5]:
print(bus)
4. 爬取地铁信息
4.1 目标网站分析
假设我们要抓取 地铁信息,这些信息通常包括:
- 地铁线路
- 各站点
- 运营时间
- 票价信息
我们将使用类似的流程来抓取地铁信息。
4.2 发送 HTTP 请求和解析数据
python
复制编辑
def fetch_metro_page(url):
response = requests.get(url)
if response.status_code == 200:
return response.text
else:
print(f"请求失败,状态码:{response.status_code}")
return None
def parse_metro_data(html):
soup = BeautifulSoup(html, "html.parser")
metros = []
for metro in soup.find_all("div", class_="metro-line"):
line_name = metro.find("h3", class_="line-name").text.strip()
stations = [station.text.strip() for station in metro.find_all("span", class_="station")]
start_time = metro.find("span", class_="start-time").text.strip()
end_time = metro.find("span", class_="end-time").text.strip()
fare = metro.find("span", class_="fare").text.strip()
metros.append({
"line_name": line_name,
"stations": stations,
"start_time": start_time,
"end_time": end_time,
"fare": fare
})
return metros
4.3 抓取多个地铁页面
python
复制编辑
def fetch_all_metro(url, pages=5):
all_metro = []
for page in range(1, pages + 1):
page_url = f"{url}?page={page}"
html = fetch_metro_page(page_url)
if html:
metros = parse_metro_data(html)
all_metro.extend(metros)
return all_metro
5. 数据存储与清洗
5.1 存储数据到 SQLite 数据库
我们可以将抓取的公交、地铁信息存入 SQLite 数据库,并进行进一步的数据分析。
python
复制编辑
def save_to_database(data, table_name, db_name="transport_data.db"):
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
# 创建表格
cursor.execute(f"""
CREATE TABLE IF NOT EXISTS {table_name} (
id INTEGER PRIMARY KEY AUTOINCREMENT,
line_name TEXT,
stations TEXT,
start_time TEXT,
end_time TEXT,
fare TEXT
)
""")
# 插入数据
for entry in data:
cursor.execute(f"""
INSERT INTO {table_name} (line_name, stations, start_time, end_time, fare)
VALUES (?, ?, ?, ?, ?)
""", (entry["line_name"], ", ".join(entry["stations"]), entry["start_time"], entry["end_time"], entry["fare"]))
conn.commit()
conn.close()
5.2 数据清洗
数据存储之前,我们需要清洗一下数据,例如去除无效数据、转换数据格式等。
python
复制编辑
def clean_data(data):
for entry in data:
# 去除多余的空格
entry["line_name"] = entry["line_name"].strip()
entry["fare"] = entry["fare"].replace("¥", "").strip()
return data
6. 数据分析与可视化
6.1 公交线路票价分布
python
复制编辑
def plot_fare_distribution(buses):
fares = [float(bus["fare"]) for bus in buses if bus["fare"].replace(".", "").isdigit()]
plt.figure(figsize=(10, 6))
sns.histplot(fares, kde=True, bins=20)
plt.title("公交票价分布")
plt.xlabel("票价 (¥)")
plt.ylabel("频率")
plt.show()
6.2 地铁线路运营时间
python
复制编辑
def plot_metro_times(metros):
start_times = [metro["start_time"] for metro in metros]
end_times = [metro["end_time"] for metro in metros]
plt.figure(figsize=(10, 6))
sns.histplot(start_times, kde=True, bins=10, color="blue", label="首班车")
sns.histplot(end_times, kde=True, bins=10, color="red", label="末班车")
plt.title("地铁线路运营时间分布")
plt.xlabel("时间")
plt.ylabel("频率")
plt.legend()
plt.show()
7. 定期抓取与更新监控
为了确保数据的实时性,我们可以设置定时任务,定期抓取公共交通数据。
python
复制编辑
import schedule
import time
def job():
print("定期抓取公共交通数据...")
buses = fetch_all_buses("https://city-bus-info.com/routes", pages=3)
metros = fetch_all_metro("https://city-metro-info.com/routes", pages=3)
buses = clean_data(buses)
metros = clean_data(metros)
save_to_database(buses, "buses")
save_to_database(metros, "metros")
# 每天抓取一次数据
schedule.every().day.at("08:00").do(job)
while True:
schedule.run_pending()
time.sleep(60)
8. 总结
通过本文教程,您可以掌握如何使用 Python 爬虫抓取城市公共交通数据,包括:
- 使用
requests
和Selenium
发送请求并解析网页内容。 - 将抓取到的公交和地铁数据存储到 SQLite 数据库。
- 使用
matplotlib
和seaborn
进行数据分析与可视化。 - 设置定时任务,实现定期抓取和数据更新。

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)