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

使用BS4与Requests爬虫仅抓取下拉列表首个选项问题排查

问题分析与解决方案

核心问题

你的爬虫在第二个URL失效的主要原因是下拉菜单的CSS选择器不匹配,同时存在变量名冲突和宽泛异常捕获的问题:

  • 选择器错误:第二个页面的下拉菜单class是venue-menu-select,而非你代码中使用的menu-selector,导致代码无法检测到下拉菜单,直接执行else分支只抓取默认的第一个菜单选项。
  • 变量名冲突:内层循环for url in menu_urls会覆盖外层遍历URL列表的url变量,虽当前逻辑不受影响,但会引发潜在的逻辑混乱。
  • 宽泛异常捕获:两层无差别except会掩盖具体错误信息,无法快速定位问题所在。

修正后的代码

import requests
from bs4 import BeautifulSoup
import re
import csv

urls = ['https://untappd.com/v/other-half-brewing-co/1360488',
        'https://untappd.com/v/beer-witch/10272294']


def get_menu_beers(soup):
    beers_all = soup.find_all('ul', {'class': 'menu-section-list'})
    
    # Open the CSV file in write mode
    with open('scraped.csv', mode='a', newline='', encoding='utf-8') as file:
        writer = csv.writer(file)
        
        for beer_group in beers_all:
            beers = beer_group.find_all('li')
            for beer in beers:
                try:
                    details = beer.find('div', {'class': 'beer-details'})
                    if not details:
                        continue
                    a_tag = details.find("a", {"class": "track-click"})
                    if not a_tag:
                        continue
                    a_href = a_tag.get("href")
                    id_num = re.findall(r'\d+', a_href)
                    beer_id = int(id_num[-1]) if id_num else None
                    name_ = a_tag.text.strip().replace('\n', ' ')
                    rating_div = details.find('div', {'class': 'caps small'})
                    rating_value = rating_div['data-rating'] if rating_div else 'N/A'
                    
                    writer.writerow([name_, rating_value])
                except Exception as e:
                    print(f"处理啤酒条目出错: {str(e)}")

for main_url in urls:         
    try:
        response = requests.get(main_url, headers={'User-agent': 'Mozilla/5.0'})
        response.raise_for_status()  # 抛出HTTP错误
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # 兼容两种下拉菜单class
        select_options = soup.find_all('select', {'class': ['menu-selector', 'venue-menu-select']})

        if select_options:
            options_list = select_options[0].find_all('option')
            menu_ids = []
            for option in options_list:
                value = option.get('value')
                if value and value.isdigit():  # 过滤空值或非数字的value
                    menu_ids.append(int(value))

            menu_urls = [f"{main_url}?menu_id={mid}" for mid in menu_ids]

            for menu_url in menu_urls:
                try:
                    res = requests.get(menu_url, headers={'User-agent': 'Mozilla/5.0'})
                    res.raise_for_status()
                    s = BeautifulSoup(res.text, 'html.parser')
                    get_menu_beers(s)
                except Exception as e:
                    print(f"抓取菜单URL {menu_url} 出错: {str(e)}")
        else:
            get_menu_beers(soup)
    except Exception as e:
        print(f"处理主URL {main_url} 出错: {str(e)}")

关键修改点

  • 兼容多种下拉菜单class:使用列表['menu-selector', 'venue-menu-select']匹配两种页面的下拉菜单,确保能检测到第二个URL的下拉选项。
  • 修复变量名冲突:将外层遍历的变量改为main_url,内层循环用menu_url,避免变量覆盖。
  • 细化异常处理:在每个可能出错的环节添加针对性异常捕获,并打印具体错误信息,方便调试。
  • 增加空值检查:对details、a_tag、rating_div等元素添加空值判断,避免因页面结构变化导致的崩溃。
  • 优化CSV编码:添加encoding='utf-8'避免中文乱码问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:57:26