使用BeautifulSoup+Requests解析站点地图时遇AttributeError问题求助
问题分析与修复方案
核心错误原因
- 变量名重复覆盖:
- 初始定义的Requests会话变量
s,在第一次循环中被赋值为soup.find_all("loc")的结果(BeautifulSoup的ResultSet对象),第二次循环执行s.get()时,实际是调用ResultSet的get方法,而该对象没有这个方法,直接抛出AttributeError。 - 外层的
urls字典被内层循环for urls in b:覆盖,导致后续存储数据的逻辑完全混乱。 - 内层循环
for b in a.findNextSiblings()中的b,覆盖了外层循环中对应字典值列表的b,同时a是字典的键(如'uk/en'),并非BeautifulSoup元素,调用a.findNextSiblings()本身就是逻辑错误。
- 初始定义的Requests会话变量
- 解析器选择错误:处理XML文件时使用
html.parser,可能导致XML标签解析异常,应该使用专门的XML解析器。
修正后的代码
import requests import bs4 # 存储最终结果的字典 result_urls = {} # 初始化Requests会话 session = requests.session() # 遍历all_sitemaps字典,region是区域标识,sitemap_files是对应sitemap文件列表 for region, sitemap_files in all_sitemaps.items(): for sitemap_file in sitemap_files: # 发送请求获取sitemap内容 response = session.get(sitemap_file) # 使用XML解析器处理内容 soup = bs4.BeautifulSoup(response.text, 'xml.parser') # 找到所有<loc>标签 loc_elements = soup.find_all("loc") for loc_elem in loc_elements: loc_text = loc_elem.get_text(strip=True) # 初始化当前loc对应的列表 if loc_text not in result_urls: result_urls[loc_text] = [] # 遍历当前<loc>标签的所有兄弟节点,提取带href属性的节点 for sibling in loc_elem.findNextSiblings(): href = sibling.get("href") if href is not None: result_urls[loc_text].append(href)
关键修改说明
- 变量名规范:
- 将Requests会话重命名为
session,避免与后续的标签结果变量冲突。 - 将存储结果的字典改为
result_urls,避免被内层循环变量覆盖。 - 循环变量改用更具语义的名称,彻底消除变量名重复问题。
- 将Requests会话重命名为
- 解析器替换:将
html.parser改为xml.parser,确保XML结构被正确解析。 - 逻辑修正:将
a.findNextSiblings()改为loc_elem.findNextSiblings(),针对每个<loc>元素去查找其兄弟节点,符合原本的业务逻辑。 - 文本处理优化:使用
get_text(strip=True)去除文本前后的空白字符,让URL更干净。
内容的提问来源于stack exchange,提问作者natan specialist
相关产品推荐
相关产品推荐

