网页抓取并导出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)
关键说明
- CSV空行问题:打开文件时添加
newline='',避免Windows系统下导出的CSV出现多余空行。 - 字段索引调整:
userinfo中各元素的索引要严格对应页面中span的顺序,需打开用户详情页查看HTML结构确认。 - 每日数据选择器:代码中
day-data等class是示例,需根据实际页面的HTML结构修改选择器,确保能正确定位每日各项数据。
内容的提问来源于stack exchange,提问作者dee
相关产品推荐
相关产品推荐

