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

使用BeautifulSoup爬取Strava网页时遇到问题

从Strava活动页面提取轨迹数据生成GPX文件

问题描述

我想把Strava上的活动转换成GPX文件,需要爬取页面里的海拔、经纬度等数据。这些数据存在带<div data-react-class=属性的标签里,重点是从{"activity":{"name"开始的那段数据。但我写的代码里,找到目标div转成字符串后用.index('altitude')会报ValueError: substring not found错误,而且我希望只用BeautifulSoup来实现数据提取,不知道该怎么做。

原代码:

import requests
from bs4 import BeautifulSoup
import csv

url = 'https://www.strava.com/activities/7487240518'
urlr = requests.get(url)

soup = BeautifulSoup(urlr.content, 'html.parser')

divdata = soup.find('div', {'data-react-class':'ActivityPublic'})
strdata = str(divdata)

print(strdata.index('altitude'))

问题原因

  1. 直接把div转字符串查找altitude失败,核心原因是Strava页面的轨迹数据依赖动态渲染,用requests.get仅能拿到初始HTML框架,没有包含完整的轨迹字段(比如altitude)。
  2. 目标数据实际存储在div的data-react-props属性里,而非div的文本内容,直接转字符串切片的方式既不可靠也容易出错。

基于BeautifulSoup的解决方案

步骤1:模拟浏览器请求获取完整页面

Strava会检测请求的User-Agent,必须添加浏览器头才能拿到包含数据的页面:

import requests
from bs4 import BeautifulSoup
import json
import gpxpy
import gpxpy.gpx

url = 'https://www.strava.com/activities/7487240518'
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'
}
urlr = requests.get(url, headers=headers)

步骤2:提取data-react-props中的JSON数据

目标div的data-react-props属性存储着包含活动轨迹的JSON字符串,解析后可直接提取所需数据:

soup = BeautifulSoup(urlr.content, 'html.parser')
divdata = soup.find('div', {'data-react-class':'ActivityPublic'})

if divdata and 'data-react-props' in divdata.attrs:
    # 解析JSON数据
    props_data = json.loads(divdata['data-react-props'])
    activity = props_data.get('activity', {})
    streams = activity.get('streams', {})
    
    # 提取经纬度、海拔轨迹流
    latlng_stream = streams.get('latlng')
    altitude_stream = streams.get('altitude')
    
    if latlng_stream and altitude_stream:
        # 创建GPX文件结构
        gpx = gpxpy.gpx.GPX()
        gpx_track = gpxpy.gpx.GPXTrack()
        gpx.tracks.append(gpx_track)
        gpx_segment = gpxpy.gpx.GPXTrackSegment()
        gpx_track.segments.append(gpx_segment)
        
        # 遍历轨迹点写入GPX
        for latlng, altitude in zip(latlng_stream['data'], altitude_stream['data']):
            lat, lng = latlng
            gpx_segment.points.append(gpxpy.gpx.GPXTrackPoint(lat, lng, elevation=altitude))
        
        # 保存GPX文件
        with open('strava_activity.gpx', 'w') as f:
            f.write(gpx.to_xml())
        print("GPX文件生成成功!")
    else:
        print("未找到轨迹数据,需用动态渲染工具加载页面")
else:
    print("未找到目标div或数据属性")

动态渲染 fallback(若静态请求仍无数据)

如果上述代码拿不到数据,说明轨迹数据是JS动态加载的,需用selenium启动浏览器加载页面后提取:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import json

driver = webdriver.Chrome()
driver.get(url)
time.sleep(3)  # 等待页面加载完成

divdata = driver.find_element(By.CSS_SELECTOR, 'div[data-react-class="ActivityPublic"]')
props_data = json.loads(divdata.get_attribute('data-react-props'))

# 后续轨迹提取、GPX生成逻辑同上述代码
driver.quit()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 02:24:32