Selenium中循环打开处理多层级分类页面链接的最高效方式是什么
Selenium多级分类链接抓取高效实现方案
原有代码核心问题
- 每次循环都重新创建Chrome浏览器实例,进程启动销毁开销极大,是效率低的核心原因
- 存在语法错误:
cats.close、wd.close缺少调用括号,WebDriverWait第一个参数传了webdriver类而非实际实例,重复定义options冗余无效 - 没有分层处理4级分类逻辑,仅实现了一级的遍历
优化实现思路
- 全程复用单个Chrome实例,通过新开/关闭标签页处理不同链接,避免重复启动浏览器进程
- 优先判断页面是否需要JS渲染:静态内容直接用requests库请求解析,比Selenium快5~10倍
- 用广度优先遍历处理4级分类,逻辑统一可维护
- 合理设置等待策略,避免硬等待浪费时间
优化后代码
import sys import requests sys.path.insert(0,'/usr/lib/chromium-browser/chromedriver') from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from bs4 import BeautifulSoup # 全局复用同一个浏览器实例,只初始化一次 options = webdriver.ChromeOptions() options.add_argument('--headless') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') # 禁止加载图片等无关资源进一步提速 options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2}) wd = webdriver.Chrome('chromedriver',options=options) domain = "替换为实际的域名前缀" # 递归处理多级分类,level参数标识当前分类层级 def process_category(url, level): # 层级超过4级直接返回 if level > 4: return # 静态页面直接用requests请求,不需要Selenium渲染 try: resp = requests.get(url, timeout=5) soup = BeautifulSoup(resp.text, "html.parser") # 遇到需要JS渲染的页面再切换到Selenium处理 except: wd.get(url) WebDriverWait(wd, 3).until(lambda d: d.find_element("tag name", "body")) soup = BeautifulSoup(wd.page_source, "html.parser") # 提取当前页分类链接 items = soup.select('ul[data-card-id="tree-list0972"]') for item in items: ul = item.find('ul') if not ul: continue for li in ul.children: if not li.a: continue href = li.a.get('href') text = li.a.text print(f"{href},{text}") # 递归处理下一级分类 full_url = domain + href process_category(full_url, level + 1) # 入口:处理第一级分类 process_category("替换为实际的入口页面URL", level=1) # 最后只关闭一次浏览器 wd.quit()
额外提速技巧
- 如果抓取量大可加线程池,并发处理多个链接,注意控制并发数避免被目标站封禁
- 可以加缓存,已经抓取过的链接直接跳过,避免重复请求
- 对需要Selenium渲染的页面,可以开启页面加载策略为
eager,不需要等所有资源加载完就开始解析,进一步提速
内容的提问来源于stack exchange,提问作者STORM
相关产品推荐
相关产品推荐

