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

网页抓取并导出CSV遇问题:userdetail使用困惑及AttributeError报错

网页抓取导出CSV的问题修复方案

一、解决AttributeError: 'NoneType' object has no attribute 'find_all'错误

这个错误的核心是你直接链式调用了find('div', id='userinfo').find_all(...),如果页面中找不到id为userinfo的div,find()会返回None,此时调用find_all()就会触发错误。

修复方法:先单独获取目标div,判断存在后再执行后续操作:

userinfo_div = usersoup.find('div', attrs={'id' : 'userinfo'})
if userinfo_div:
    userinfo = userinfo_div.find_all('span', attrs={'class' : 'val'})
    # 后续数据处理逻辑
else:
    print(f"用户页面 {urltoget + href} 未找到userinfo模块,跳过")
    continue

二、处理userdetail[].text的错误

你的代码里根本没定义userdetail变量,而且userdetail[]这种写法本身不符合Python语法。结合CSV表头,应该从userinfo(所有class为val的span元素)中提取对应字段,再补充每日数据(日期、当日饮水量等)。

完整修改后的代码

import requests as r
from bs4 import BeautifulSoup
import csv
import time as t
import random as rnd

urltoget='http://drd.ba.ttu.edu/isqs3358/hw/hw1/'
filename1 = 'exercisedata.csv'
lowval = 5
highval = 7

res=r.get(urltoget)
soup = BeautifulSoup(res.content, 'lxml')

user = soup.find('div', attrs={'id':'UserIndex'})
userurls = user.find_all('a')

with open(filename1,'w', newline='') as exercisedata:  # 添加newline=''避免CSV空行
    datawriter = csv.writer(exercisedata, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)

    datawriter.writerow(['rank', 'user_id', 'first_name', 'last_name', 'avg_sleep', 'avg_water','avg_step','day', 'day_water', 'day_step', 'metric'])
    for user in userurls:
        href = user['href']
        user_id = href.split('=')[1]
        userres = r.get(urltoget + href)
        usersoup = BeautifulSoup(userres.content, 'lxml')
        
        # 修复AttributeError问题
        userinfo_div = usersoup.find('div', attrs={'id' : 'userinfo'})
        if not userinfo_div:
            print(f"跳过用户 {user_id}:未找到用户信息模块")
            continue
        
        userinfo = userinfo_div.find_all('span', attrs={'class' : 'val'})
        # 提取用户基础信息(需根据页面实际span顺序调整索引)
        if len(userinfo) >=7:
            rank = userinfo[0].text.strip()
            first_name = userinfo[1].text.strip()
            last_name = userinfo[2].text.strip()
            avg_sleep = userinfo[3].text.strip()
            avg_water = userinfo[4].text.strip()
            avg_step = userinfo[5].text.strip()
        else:
            print(f"用户 {user_id} 的信息字段不全,跳过")
            continue
        
        # 提取每日数据(需根据页面实际HTML结构修改选择器)
        day_items = usersoup.find_all('div', class_='day-data')
        for day_item in day_items:
            day = day_item.find('span', class_='day').text.strip()
            day_water = day_item.find('span', class_='day-water').text.strip()
            day_step = day_item.find('span', class_='day-step').text.strip()
            metric = day_item.find('span', class_='metric').text.strip()
            
            # 写入完整一行数据
            datawriter.writerow([rank, user_id, first_name, last_name, avg_sleep, avg_water, avg_step, day, day_water, day_step, metric])
        
        timetosleep = rnd.randint(lowval, highval) + rnd.random()
        t.sleep(timetosleep)

关键说明

  1. CSV空行问题:打开文件时添加newline='',避免Windows系统下导出的CSV出现多余空行。
  2. 字段索引调整:userinfo中各元素的索引要严格对应页面中span的顺序,需打开用户详情页查看HTML结构确认。
  3. 每日数据选择器:代码中day-data等class是示例,需根据实际页面的HTML结构修改选择器,确保能正确定位每日各项数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:30:57