TypechoJoeTheme

至尊技术网

统计
登录
用户名
密码

实战:用Python爬取动态加载的TfL自行车数据(附完整代码)

2025-09-05
/
0 评论
/
4 阅读
/
正在检测是否收录...
09/05


一、动态数据爬取的难点突破

当我们在浏览器中打开TfL自行车使用数据页面时,看似简单的"Download"按钮背后藏着技术玄机。传统爬虫直接获取HTML源码的方法在这里完全失效——因为数据是通过JavaScript动态加载的。

通过Chrome开发者工具分析网络请求(快捷键F12),我们会发现点击下载时实际触发了对https://data.london.gov.uk/download/number-bicycle-hires/...的POST请求。这种设计是现代Web应用常用的反爬手段,但Python的requests库配合正确参数就能完美破解。

二、逆向工程分析API

关键步骤解析:
1. 请求头伪装:服务器会校验User-Agent等头部信息
python headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', 'Referer': 'https://data.london.gov.uk/', 'X-Requested-With': 'XMLHttpRequest' }

  1. 表单参数提取:通过浏览器监测捕获必要参数
    python payload = { 'resource_id': 'bicycle-hires', 'format': 'csv', 'q': '2023', '_token': 'abc123' # 动态变化的CSRF令牌 }

  2. 会话保持:使用Session对象维持cookies
    python with requests.Session() as s: s.get('https://data.london.gov.uk/') # 首次获取cookies response = s.post(api_url, headers=headers, data=payload)

三、完整爬虫实现代码

python
import requests
from bs4 import BeautifulSoup
import pandas as pd

def fetchtflbikedata(year): baseurl = "https://data.london.gov.uk"
session = requests.Session()

# 第一步:获取初始页面提取CSRF令牌
index_page = session.get(f"{base_url}/dataset/number-bicycle-hires")
soup = BeautifulSoup(index_page.text, 'html.parser')
token = soup.select_one('meta[name="csrf-token"]')['content']

# 第二步:构造API请求
api_endpoint = f"{base_url}/download/number-bicycle-hires"
headers = {
    'User-Agent': 'Mozilla/5.0',
    'X-CSRF-TOKEN': token
}
payload = {
    'year': year,
    'format': 'csv'
}

# 第三步:流式下载大容量CSV
response = session.post(api_endpoint, headers=headers, data=payload, stream=True)
with open(f'tfl_bikes_{year}.csv', 'wb') as f:
    for chunk in response.iter_content(chunk_size=1024):
        if chunk:
            f.write(chunk)

# 数据预览
df = pd.read_csv(f'tfl_bikes_{year}.csv')
print(f"成功获取{year}年数据,共{len(df)}条记录")
return df

示例:获取2023年数据

data2023 = fetchtflbikedata(2023)

四、数据处理与可视化进阶

获取数据只是第一步,真正的价值在于数据分析:python
import matplotlib.pyplot as plt

数据清洗

data2023['Day'] = pd.todatetime(data2023['Day']) data2023.set_index('Day', inplace=True)

月度聚合分析

monthlydata = data2023.resample('M').sum()

可视化

plt.figure(figsize=(12,6))
monthlydata['Number of bicycle hires'].plot(kind='bar') plt.title('2023年伦敦自行车月租用量趋势') plt.ylabel('租用次数') plt.grid(axis='y') plt.tightlayout()
plt.savefig('tflbiketrend.png')

五、反爬策略应对方案

  1. IP限制:使用time.sleep(random.uniform(1,3))模拟人类操作间隔
  2. 验证码:集成第三方服务如2Captcha
  3. 请求频率:通过代理池轮换IP(推荐使用python-requests-ip-rotator
  4. 数据校验:添加异常重试机制python
    from tenacity import retry, stopafterattempt

@retry(stop=stopafterattempt(3))
def safe_fetch(url):
try:
return session.get(url)
except RequestException as e:
print(f"请求失败: {e}")
raise


通过这个真实案例,我们不仅掌握了动态CSV数据的抓取技术,更学会了如何像数据分析师一样思考。建议读者尝试修改参数获取不同年份数据,或者结合天气数据做更深度的关联分析。完整代码已测试通过,可直接应用于类似政府开放数据平台的数据采集场景。

Python爬虫动态数据抓取TfL API解析CSV数据处理requests库实战
朗读
赞(0)
版权属于:

至尊技术网

本文链接:

https://www.zzwws.cn/archives/37828/(转载时请注明本文出处及文章链接)

评论 (0)