无法抓取TfL骑行数据站点CSV文件,求有效解决方案
解决方案
返回服务条款链接不代表无法抓取该站点,问题出在两个地方:请求头缺失导致被重定向,以及访问的URL不是目标文件列表页。
问题原因
- 你访问的根域名本身只展示服务条款,目标文件列表在
usage-stats子目录下,正确URL是https://cycling.data.tfl.gov.uk/usage-stats/。 - 未携带
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
相关产品推荐
相关产品推荐

