爬虫开发需求:递归提取AmericanFlags.com的商品页面URL
递归遍历分类URL提取商品页面URL解决方案
我正在爬取网站https://www.americanflags.com/flags.html,需要提取各类旗帜的商品页面URL。目前已抓取分类URL并存储在listofurls列表中:
listofurls = ['https://www.americanflags.com/flags/military-flags.html', 'https://www.americanflags.com/flags/military-flags/pow-mia-flags.html', 'https://www.americanflags.com/flags/police-fire-thin-line-ems.html', 'https://www.americanflags.com/flags/911-honor-flags.html', 'https://www.americanflags.com/flags/government-specified-flags-accessories.html', 'https://www.americanflags.com/flags/gift-certificates.html', 'https://www.americanflags.com/flags/novelty-celebration-flags.html', 'https://www.americanflags.com/flags/holiday-seasonal-flags-banners.html', 'https://www.americanflags.com/flags/nautical-flags.html', 'https://www.americanflags.com/flags/city-flags.html', 'https://www.americanflags.com/flags/political-flags.html', 'https://www.americanflags.com/flags/iso-flags.html', 'https://www.americanflags.com/flags/desk-stick-flag-sets.html', 'https://www.americanflags.com/flags/us-state-territory-flags.html', 'https://www.americanflags.com/flags/world-flags.html', 'https://www.americanflags.com/flags/historic-flags.html', 'https://www.americanflags.com/flags/sports-flags.html', 'https://www.americanflags.com/flags/religious-flags.html', 'https://www.americanflags.com/flags/advertising-flags.html', 'https://www.americanflags.com/flags/custom-flags-banners.html', 'https://www.americanflags.com/flags/political-flags/protest-flags.html']
需求说明
- 若URL对应商品页面,则将其存入
mainlist - 部分分类URL包含子分类,需递归遍历所有分类URL,直到找到商品页面
- 示例:
https://www.americanflags.com/flags/military-flags.html是包含子分类的页面,https://www.americanflags.com/flags/police-fire-thin-line-ems.html是商品页面
原代码问题分析
原代码存在以下缺陷:
- 遍历列表时使用
pop(indx)会导致索引错乱,后续元素无法被正确遍历 - 递归逻辑混乱,嵌套循环处理子分类URL时会跳过元素
- 异常处理过于宽泛,且存在未定义变量
t - 依赖异常判断页面类型不可靠,应该基于页面特征明确区分分类页和商品页
修复后的代码
import requests from bs4 import BeautifulSoup as bs mainlist = [] cookies = {} # 替换为你的实际cookies headers = {} # 替换为你的实际请求头 def process_url(url): try: res = requests.get(url, cookies=cookies, headers=headers) res.raise_for_status() # 捕获HTTP请求错误 soup = bs(res.content, 'lxml') # 判断是否为分类页面:检查是否存在子分类链接 sub_category_links = soup.select('div.wrapper > a') if sub_category_links: # 遍历所有子分类URL,递归处理 for link in sub_category_links: sub_url = link['href'] # 处理相对路径URL,拼接为完整地址 if not sub_url.startswith('http'): sub_url = f"https://www.americanflags.com{sub_url}" process_url(sub_url) else: # 无分类链接,判定为商品页面,加入结果列表 mainlist.append(url) except Exception as e: print(f"处理URL {url} 时出错: {e}") # 遍历初始分类URL列表 for url in listofurls: process_url(url) # 输出结果 print("提取到的商品页面URL:") for url in mainlist: print(url)
代码关键说明
- 使用递归函数
process_url处理每个URL,逻辑清晰:- 请求页面并解析HTML
- 检查页面是否存在子分类链接,有则递归处理每个子分类
- 无分类链接则判定为商品页面,加入结果列表
- 自动处理相对路径URL,确保地址完整有效
- 加入HTTP请求错误捕获,避免无效页面被误判
- 遍历初始列表时不修改原列表,避免索引错乱问题
- 异常处理明确,打印错误信息便于排查
内容的提问来源于stack exchange,提问作者Adnan Zafar
相关产品推荐
相关产品推荐

