# 怎么利用Python爬取城市公交站點
## 前言
在智慧城市建設和交通規劃領域,公交站點數據是重要的基礎信息。本文將詳細介紹如何使用Python技術棧實現城市公交站點數據的爬取,包含從需求分析到數據存儲的完整流程。
## 一、技術選型與環境準備
### 1.1 核心工具包
```python
# 推薦工具庫
import requests # 網絡請求
from bs4 import BeautifulSoup # HTML解析
import pandas as pd # 數據處理
import json # JSON處理
import re # 正則表達式
import time # 延時控制
from fake_useragent import UserAgent # 隨機UA生成
pip install requests beautifulsoup4 pandas fake-useragent| 反爬類型 | 解決方案 |
|---|---|
| UA檢測 | 隨機UserAgent輪換 |
| IP限制 | 代理IP池/請求間隔控制 |
| 驗證碼 | OCR識別/打碼平臺 |
| 動態加載 | Selenium/Puppeteer |
def get_bus_stops(city, line, api_key):
url = f"https://restapi.amap.com/v3/bus/linename?s=rsv3&extensions=all"
params = {
"key": api_key,
"city": city,
"keywords": line,
"output": "json"
}
try:
response = requests.get(url, params=params)
if response.status_code == 200:
return response.json()
else:
print(f"請求失敗,狀態碼:{response.status_code}")
return None
except Exception as e:
print(f"發生異常:{str(e)}")
return None
def parse_bus_data(data):
stops = []
for line in data['buslines']:
for stop in line['busstops']:
stop_info = {
'line_name': line['name'],
'line_id': line['id'],
'stop_name': stop['name'],
'stop_id': stop['id'],
'location': stop['location'],
'sequence': stop['sequence']
}
stops.append(stop_info)
return pd.DataFrame(stops)
當目標網站采用JavaScript動態加載時:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("http://example.com/bus")
stops = driver.find_elements(By.CLASS_NAME, "bus-stop")
data = [stop.text for stop in stops]
driver.quit()
| 存儲方式 | 優點 | 缺點 |
|---|---|---|
| CSV | 易讀性好,兼容性強 | 不支持復雜結構 |
| MySQL | 查詢效率高,支持事務 | 需要數據庫服務 |
| MongoDB | 適合非結構化數據 | 資源占用較大 |
| SQLite | 輕量級,單文件 | 并發性能一般 |
class BusSpider:
def __init__(self, city):
self.base_url = "https://example.com/api"
self.city = city
self.session = requests.Session()
self.session.headers.update({'User-Agent': UserAgent().random})
def get_lines(self):
# 獲取所有公交線路
pass
def get_stops(self, line_id):
# 獲取線路站點
pass
def save_to_sql(self, data):
# 數據庫存儲
pass
def run(self):
lines = self.get_lines()
for line in lines:
stops = self.get_stops(line['id'])
self.save_to_sql(stops)
time.sleep(1.5)
def clean_data(df):
# 坐標分割
df[['lng', 'lat']] = df['location'].str.split(',', expand=True)
# 去除空值
df = df.dropna(subset=['stop_name'])
# 標準化站名
df['stop_name'] = df['stop_name'].str.replace(r'\(.*?\)', '')
return df
import folium
def create_map(df, city_center):
m = folium.Map(location=city_center, zoom_start=12)
for _, row in df.iterrows():
folium.Marker(
[row['lat'], row['lng']],
popup=row['stop_name']
).add_to(m)
return m
Q1: 遇到403禁止訪問錯誤怎么辦? A: 檢查Headers完整性,特別是Referer和Cookies
Q2: 數據出現亂碼如何解決?
response.encoding = response.apparent_encoding
Q3: 如何應對頁面結構變動? - 使用更寬松的CSS選擇器 - 增加異常處理邏輯 - 定期維護爬蟲代碼
通過本文介紹的方法,您可以構建完整的公交數據采集系統。建議在實際項目中: 1. 優先使用官方API 2. 做好數據更新維護機制 3. 考慮將數據用于智能公交系統等實際應用
注意:本文所有代碼示例僅供參考,實際使用時請遵守目標網站的相關規定。 “`
本文共包含約3000字內容,涵蓋從基礎到進階的公交站點爬取技術。如需完整可運行代碼,需要根據具體目標網站進行參數調整和功能完善。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。