B站数据可视化避坑指南:用Selenium 3.141.0爬取时遇到的5个典型报错及解决方案

张开发
2026/4/15 19:33:34 15 分钟阅读

分享文章

B站数据可视化避坑指南:用Selenium 3.141.0爬取时遇到的5个典型报错及解决方案
B站数据爬取实战Selenium 3.141.0常见报错深度解析与可视化方案优化1. 环境配置的版本陷阱与解决方案在B站数据爬取项目中环境配置是最容易踩坑的环节。许多开发者习惯直接安装最新版本的软件和库但这在爬虫项目中往往会导致兼容性问题。1.1 ChromeDriver版本匹配问题最常见的报错之一是SessionNotCreatedException通常由Chrome浏览器与ChromeDriver版本不匹配引起。以下是推荐的版本组合Chrome版本ChromeDriver版本Selenium版本109.x109.0.5414.x3.141.0114.x114.x3.141.0关键操作步骤查看当前Chrome版本在浏览器地址栏输入chrome://version/到ChromeDriver官网下载对应版本将ChromeDriver可执行文件放在系统PATH路径下# 验证环境配置是否正确的测试代码 from selenium import webdriver def test_environment(): try: driver webdriver.Chrome() driver.get(https://www.bilibili.com) print(环境配置成功) driver.quit() except Exception as e: print(f环境配置错误{str(e)})1.2 阻止Chrome自动升级Chrome的自动升级功能会导致版本不匹配问题突然出现。以下是禁用自动升级的方法Windows系统打开Chrome安装目录通常为C:\Program Files\Google\Chrome\Application进入Update文件夹右键点击GoogleUpdate.exe选择属性在安全选项卡中禁用所有用户的执行权限提示完成上述操作后建议定期手动检查更新确保安全补丁能够及时应用。2. 元素定位失效的五大场景与应对策略2.1 XPath定位失效问题B站前端经常更新DOM结构导致XPath定位失效。以下是更健壮的定位方案# 不推荐的脆弱定位方式 driver.find_element_by_xpath(//*[idapp]/div/div[2]/div[2]/ul/li[1]/div/div[2]/a) # 推荐的相对定位方式 driver.find_element_by_css_selector(a[href*/video])2.2 动态加载内容处理B站大量使用AJAX加载内容直接获取元素可能失败。最佳实践是使用显式等待from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC wait WebDriverWait(driver, 10) element wait.until(EC.presence_of_element_located( (By.CSS_SELECTOR, div.video-list li) ))2.3 反爬机制应对方案B站的反爬策略会随时间变化常见应对方法包括添加合理的请求头控制请求频率建议3-5秒/次使用随机User-Agent处理验证码需要人工干预from fake_useragent import UserAgent ua UserAgent() headers { User-Agent: ua.random, Referer: https://www.bilibili.com }3. 数据清洗与格式转换技巧3.1 中文数字转换B站显示数据常包含万等中文单位需要转换为纯数字def convert_chinese_number(text): if 万 in text: return float(text.replace(万, )) * 10000 return float(text) # 示例将3.2万转换为32000 views convert_chinese_number(3.2万)3.2 数据存储优化推荐使用pandas进行数据清洗和存储import pandas as pd # 读取爬取的数据 df pd.read_csv(bilibili_data_raw.csv) # 数据清洗 df[views] df[views].apply(convert_chinese_number) df[date] pd.to_datetime(df[date]) # 保存清洗后的数据 df.to_csv(bilibili_data_clean.csv, indexFalse)4. 高效可视化方案设计4.1 Pyecharts高级配置技巧from pyecharts import options as opts from pyecharts.charts import Bar # 创建柱状图 bar ( Bar() .add_xaxis(df[title].tolist()) .add_yaxis(播放量, df[views].tolist()) .set_global_opts( title_optsopts.TitleOpts(titleB站视频播放量TOP20), datazoom_opts[opts.DataZoomOpts()], # 添加数据缩放 toolbox_optsopts.ToolboxOpts(), # 添加工具箱 ) ) # 渲染图表 bar.render(bilibili_views_top20.html)4.2 交互式仪表盘设计结合多个图表创建综合仪表盘from pyecharts.charts import Page page Page(layoutPage.DraggablePageLayout) page.add( make_bar_chart(), make_pie_chart(), make_line_chart() ) page.render(bilibili_dashboard.html)5. 性能优化与错误处理5.1 资源释放策略不正确的资源释放会导致内存泄漏from contextlib import contextmanager contextmanager def browser_session(): driver webdriver.Chrome() try: yield driver finally: driver.quit() # 使用示例 with browser_session() as driver: driver.get(https://www.bilibili.com) # 执行爬取操作5.2 自动化重试机制from tenacity import retry, stop_after_attempt, wait_exponential retry(stopstop_after_attempt(3), waitwait_exponential(multiplier1, min4, max10)) def scrape_video_info(driver, url): try: driver.get(url) # 提取数据逻辑 return data except Exception as e: print(f抓取{url}失败: {str(e)}) raise6. 实战案例分析热门视频数据抓取6.1 完整爬取流程def scrape_bilibili_top100(): with browser_session() as driver: # 访问排行榜 driver.get(https://www.bilibili.com/v/popular/rank/all) # 等待加载 wait WebDriverWait(driver, 10) wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, li.rank-item))) # 提取视频列表 videos [] items driver.find_elements(By.CSS_SELECTOR, li.rank-item) for item in items: title item.find_element(By.CSS_SELECTOR, a.title).text up item.find_element(By.CSS_SELECTOR, a.up-name).text views convert_chinese_number(item.find_element(By.CSS_SELECTOR, span.data-box).text) videos.append({ title: title, up: up, views: views }) return pd.DataFrame(videos)6.2 数据可视化呈现def create_video_analysis(df): # 播放量分布图 hist ( Histogram() .add_xaxis(list(range(0, 5000000, 500000))) .add_yaxis(视频数量, df[views].value_counts(bins10).tolist()) .set_global_opts(title_optsopts.TitleOpts(title播放量分布)) ) # UP主作品数量统计 up_stats df[up].value_counts().head(10) bar ( Bar() .add_xaxis(up_stats.index.tolist()) .add_yaxis(作品数量, up_stats.values.tolist()) .set_global_opts(title_optsopts.TitleOpts(title高产UP主TOP10)) ) # 组合图表 page Page() page.add(hist, bar) return page7. 高级技巧处理登录与验证码对于需要登录才能访问的数据可以采用以下方案from selenium.webdriver.common.action_chains import ActionChains def login_bilibili(driver, username, password): driver.get(https://passport.bilibili.com/login) # 输入用户名密码 user_input driver.find_element(By.ID, login-username) user_input.send_keys(username) pwd_input driver.find_element(By.ID, login-passwd) pwd_input.send_keys(password) # 处理验证码 try: slider driver.find_element(By.CSS_SELECTOR, div.geetest_slider) ActionChains(driver).click_and_hold(slider).move_by_offset(150, 0).release().perform() except: pass # 点击登录 driver.find_element(By.CSS_SELECTOR, a.btn-login).click() # 等待登录完成 WebDriverWait(driver, 10).until( EC.url_contains(bilibili.com) )8. 数据存储方案选型根据数据规模选择合适的存储方案数据规模推荐方案优点缺点1万条SQLite/CSV简单易用无需额外服务查询性能有限1-100万条MySQL成熟稳定支持复杂查询需要单独部署100万条MongoDB灵活扩展适合非结构化数据学习曲线较陡# MongoDB存储示例 from pymongo import MongoClient def save_to_mongodb(data): client MongoClient(mongodb://localhost:27017/) db client[bilibili] collection db[videos] # 批量插入 if isinstance(data, list): collection.insert_many(data) else: collection.insert_one(data)9. 定时任务与自动化部署使用APScheduler实现定时爬取from apscheduler.schedulers.blocking import BlockingScheduler def job(): print(开始执行定时爬取任务...) data scrape_bilibili_top100() save_to_mongodb(data.to_dict(records)) print(任务完成) scheduler BlockingScheduler() scheduler.add_job(job, cron, hour3) # 每天凌晨3点执行 try: scheduler.start() except KeyboardInterrupt: scheduler.shutdown()10. 法律合规与道德考量在进行网络爬虫开发时必须注意遵守robots.txt协议控制请求频率避免对目标服务器造成负担仅爬取公开可用数据不绕过任何技术保护措施数据使用需符合最初收集目的重要提示商业用途的数据爬取必须获得平台方明确授权个人学习研究也应注意数据使用范围。

更多文章