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

如何获取网站分类/子分类各层级classname?解决四级报错问题

问题描述

我需要获取某连锁餐厅门店定位网站各层级元素的classname,网站结构分为3或4级,需逐层钻取:

  • 第1级:初始页面显示各州链接
  • 第2级:点击州后显示对应城市
  • 第3级:点击城市后显示对应门店位置
  • 第4级:点击门店后显示地址信息

当前我的Selenium代码可以获取前3级的classname,但第4级报错'NoneType' object is not subscriptable。我的逻辑是查找包含指定文本的锚点元素并获取其classname,禁止使用xpath。请帮忙优化代码,实现获取地址的classname,同时处理仅存在3级的场景(当城市仅有一个门店时为3级,多个门店时为4级)。

原代码如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time


# function to get url and class in different levels
def get_url_class(url,level):
    driver.get(url) 
    time.sleep(3)
    links = driver.find_elements(By.TAG_NAME, "a")
    
    for lnk in links:
        if level in lnk.text:
            if lnk.get_attribute("class"):
                new_class = lnk.get_attribute("class")
                new_url = lnk.get_attribute("href")
                return [new_class,new_url]


#  Open chromedriver
driver = webdriver.Chrome()

# Defining texts to search for each element
state="Alabama"    # --> Level #1
city="Huntsville"  # --> Level #2
location="South Memorial Pkwy, Huntsville"  # --> Level #3
address="11375 South Memorial Pkwy"  # --> Level #4

initial_url = "https://locations.bojangles.com/"

# Level #1 (Get state´s url and class)
level1 = get_url_class(initial_url,state)
print("className:" + level1[0] + ", url: "+ level1[1])

# Level #2 (Get cities´ url and class)
level2 = get_url_class(level1[1],city)
print("className:" + level2[0] + ", url: "+ level2[1])

# Level #3 (Get location's url and class)
level3 = get_url_class(level2[1],location)
print("className:" + level3[0] + ", url: "+ level3[1])

# Level #4 (Get address' url and class)
level4 = get_url_class(level3[1],address)
print("className:" + level4[0] + ", url: "+ level4[1])


driver.quit()
解决方案

问题根源

  1. 第4级页面的地址元素通常不是<a>标签,原代码通过By.TAG_NAME, "a"找不到目标元素,函数返回None,后续访问level4[0]触发下标错误。
  2. 原代码未处理3级场景:当城市只有一个门店时,点击城市直接进入地址页面,不存在第3级门店列表。

优化后代码

from selenium import webdriver
from selenium.webdriver.common.by import By
import time

def get_target_info(url, target_text, is_address=False):
    driver.get(url)
    time.sleep(3)
    
    if is_address:
        # 地址页面查找包含目标文本的地址元素(非链接)
        address_elements = driver.find_elements(By.CLASS_NAME, "Address-addressLine")
        for elem in address_elements:
            if target_text in elem.text:
                return [elem.get_attribute("class"), None]
        # 兜底备选类名
        fallback_elements = driver.find_elements(By.CLASS_NAME, "c-address")
        for elem in fallback_elements:
            if target_text in elem.text:
                return [elem.get_attribute("class"), None]
        return [None, None]
    else:
        # 前3级查找带目标文本的链接
        links = driver.find_elements(By.TAG_NAME, "a")
        for lnk in links:
            if target_text in lnk.text and lnk.get_attribute("href"):
                return [lnk.get_attribute("class"), lnk.get_attribute("href")]
        # 检查是否直接进入地址页面(3级场景)
        return get_target_info(url, target_text, is_address=True)

# 初始化浏览器
driver = webdriver.Chrome()

# 目标文本定义
state = "Alabama"          # 第1级
city = "Huntsville"        # 第2级
location = "South Memorial Pkwy, Huntsville"  # 第3级
address = "11375 South Memorial Pkwy"        # 第4级

initial_url = "https://locations.bojangles.com/"

# 逐层获取信息
level1 = get_target_info(initial_url, state)
print(f"第1级 className: {level1[0]}, url: {level1[1]}")

level2 = get_target_info(level1[1], city)
print(f"第2级 className: {level2[0]}, url: {level2[1]}")

# 处理3级/4级分支逻辑
if level2[1]:
    level3 = get_target_info(level2[1], location)
    print(f"第3级 className: {level3[0]}, url: {level3[1]}")
    if level3[1]:
        level4 = get_target_info(level3[1], address, is_address=True)
        print(f"第4级 className: {level4[0]}")
    else:
        print(f"当前为3级结构,地址className: {level3[0]}")
else:
    print(f"当前为3级结构,地址className: {level2[0]}")

driver.quit()

优化说明

  • 拆分地址级处理:针对地址元素非链接的特性,直接通过常见地址类名查找目标元素,规避xpath。
  • 自动适配3级场景:如果某一级返回的next_url为None,判定已进入地址页面,直接返回地址元素classname。
  • 增加兜底逻辑:补充备选地址类名查找,提升页面结构变化时的兼容性。
  • 分支逻辑清晰:通过is_address参数区分普通链接级和地址级的处理逻辑。

内容的提问来源于stack exchange,提问作者Rasec Malkic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:04:59