带URL循环的Python爬虫函数无法返回全部数据的技术问询
问题1:批量处理URL列表报错的解决方案
你遇到的'list' object has no attribute 'timeout'错误,本质是urlopen()只能接受单个URL字符串,但你直接传入了整个URL列表。要批量获取所有餐厅数据,需要修改函数逻辑,让它遍历列表里的每个URL,逐个处理并收集结果。
修正后的代码
from urllib.request import urlopen import bs4 def get_inspect_detail(url_list): # 初始化结果列表,避免全局变量污染 result = [] # 遍历每个URL逐个处理 for url in url_list: try: html = urlopen(url) soup = bs4.BeautifulSoup(html.read(), 'lxml') details = soup.find_all('font', {'face': 'verdana'})[10:] # 防止索引越界,先检查数据长度 if len(details) >= 5: site_name = details[0].text.strip() lic_num = details[2].text.strip() site_rank = details[4].text.strip() # 构造单条餐厅数据字典 restaurant_data = { 'Restaurant': site_name, 'License': lic_num, 'Rank': site_rank, } result.append(restaurant_data) else: print(f"URL {url} 的数据格式异常,跳过") except Exception as e: print(f"处理URL {url} 时出错: {str(e)}") return result # 调用示例:传入整个URL列表 url_list = ["你的URL1", "你的URL2", "你的URL3"] # 替换成实际列表 all_restaurant_data = get_inspect_detail(url_list)
关键修改点说明:
- 新增
for url in url_list循环,逐个处理每个URL,匹配urlopen()的参数要求 - 将
detailsLib改为局部变量restaurant_data,避免全局变量干扰结果 - 添加异常处理和长度检查,防止单个URL出错导致整个程序崩溃
- 用
.strip()先做基础空白清理,后续可叠加正则处理
问题2:数据清理时机的选择
关于正则处理的时机,两种方案都可行,可根据你的需求和代码复杂度选择:
方案1:函数内逐个处理数据
- 优点:爬取和清理逻辑绑定,拿到数据后直接处理,后续使用时无需再做清理;如果某条数据清理失败,可在爬取阶段就标记或跳过,避免无效数据进入结果集。
- 适用场景:清理规则简单,或需要确保每条数据都是干净的再存入结果。
- 示例:在构造字典前加入正则处理:
import re # 示例:清理License字段中的非数字字符 cleaned_lic_num = re.sub(r'\D', '', lic_num)
方案2:函数外统一处理字典中特定键的值
- 优点:爬取和清理逻辑分离,代码结构更清晰;如果后续需要调整清理规则,只需修改统一处理的代码,不用动爬取逻辑。
- 适用场景:清理规则复杂,或需要对所有数据做统一批量处理(比如批量替换、统计)。
- 示例:
import re def clean_license_data(data_list): for item in data_list: # 统一清理所有条目License字段 item['License'] = re.sub(r'\D', '', item['License']) return data_list # 先爬取所有数据,再统一清理 all_restaurant_data = get_inspect_detail(url_list) cleaned_data = clean_license_data(all_restaurant_data)
个人建议
如果你的正则规则比较固定,优先选方案1,能减少后续额外处理步骤;如果规则可能频繁调整,或需要对多字段做统一处理,选方案2更便于维护。
内容的提问来源于stack exchange,提问作者DRay
相关产品推荐
相关产品推荐

