You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法抓取TfL骑行数据站点CSV文件,求有效解决方案

解决方案

返回服务条款链接不代表无法抓取该站点,问题出在两个地方:请求头缺失导致被重定向,以及访问的URL不是目标文件列表页。

问题原因

  1. 你访问的根域名本身只展示服务条款,目标文件列表在usage-stats子目录下,正确URL是https://cycling.data.tfl.gov.uk/usage-stats/。
  2. 未携带User-Agent请求头的爬虫请求会被站点重定向到服务条款页面,而非返回文件列表。

修正后的代码

1. 抓取2021-2023年CSV文件链接

import requests
from bs4 import BeautifulSoup

def fetch_target_csv_links(url):
    # 模拟浏览器请求头,避免被重定向
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    
    if response.status_code != 200:
        print(f"请求失败,状态码:{response.status_code}")
        return []
    
    soup = BeautifulSoup(response.text, "html.parser")
    target_links = []
    target_years = {'2021', '2022', '2023'}
    
    for link in soup.find_all("a"):
        href = link.get("href")
        # 筛选CSV文件,且文件名包含目标年份
        if href and href.endswith('.csv'):
            if any(year in href for year in target_years):
                # 拼接完整URL(处理相对路径)
                full_url = url + href if href.startswith('/') else href
                target_links.append(full_url)
    
    return target_links

# 调用函数,传入正确的目录URL
csv_links = fetch_target_csv_links("https://cycling.data.tfl.gov.uk/usage-stats/")
print(f"找到{len(csv_links)}个目标CSV文件")

2. 批量下载CSV文件

import os
import time

def batch_download_csvs(links, save_dir='tfl_cycling_data'):
    os.makedirs(save_dir, exist_ok=True)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
    }
    
    for idx, link in enumerate(links, 1):
        filename = link.split('/')[-1]
        save_path = os.path.join(save_dir, filename)
        
        try:
            response = requests.get(link, headers=headers, timeout=10)
            response.raise_for_status()
            with open(save_path, 'wb') as f:
                f.write(response.content)
            print(f"[{idx}/{len(links)}] 已下载:{filename}")
            time.sleep(1)  # 添加间隔,避免服务器压力
        except Exception as e:
            print(f"[{idx}/{len(links)}] 下载失败:{link},错误:{str(e)}")

# 执行批量下载
batch_download_csvs(csv_links)

注意事项

  • 遵守站点爬虫规则,不要过度频繁请求,代码中已添加1秒间隔。
  • 若文件名格式有变化,可调整年份筛选逻辑适配实际命名规则。

内容的提问来源于stack exchange,提问作者a_jelly_fish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:20:27