尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python与Selenium浏览器自动化:从原理到实战的合规应用指南

Python与Selenium浏览器自动化:从原理到实战的合规应用指南 1. 从一次自动化需求谈起为什么有人想“刷”播放量在内容创作领域视频的播放量、点赞、评论等数据常常被创作者视为作品影响力的直观体现有时也关系到平台的推荐算法和潜在的商业合作机会。因此围绕如何“提升”这些数据衍生出了各种各样的讨论和尝试。今天要聊的就是利用 Python 和 Selenium 自动化工具模拟真实用户行为来增加 B 站视频播放量这个话题。我必须在一开始就强调本文旨在探讨技术实现的原理、过程与潜在风险仅供学习自动化测试和网页交互技术之用绝不鼓励、也坚决反对任何形式的刷量、作弊或干扰平台正常秩序的行为。任何试图破坏平台公平性、滥用资源的行为都可能违反平台规则甚至相关法律法规导致账号封禁、法律追责等严重后果。那么抛开“刷量”这个敏感目的这个技术组合本身有什么价值呢对于测试工程师、数据分析师或者希望研究网页行为的开发者来说Python Selenium 是一个极其强大的组合。Selenium 是一个用于 Web 应用程序测试的工具它可以直接运行在浏览器中模拟真实用户的所有操作比如点击、输入、滚动、等待页面加载等。结合 Python 强大的脚本能力和丰富的生态库我们可以自动化完成许多重复性的网页操作任务。例如自动化进行跨浏览器的功能回归测试、定时抓取需要登录后才能查看的网页数据在遵守robots.txt和服务条款的前提下、或者研究某个网页应用的交互逻辑。理解如何用代码“驱动”浏览器是一项非常实用的技能。所以当我们看到“python selenium 刷B站播放量”这个标题时更应该关注其背后的技术实质如何使用代码精确地控制浏览器完成一系列复杂的、带有状态维持的网页操作序列。这涉及到浏览器驱动管理、页面元素定位、等待策略、反自动化检测规避等多个关键技术点。接下来我将以一个完全合规的学习视角——例如“自动化观看自己发布的某个教学视频以检查其在不同网络环境下的播放流畅度”——来拆解整个技术流程并深入探讨其中的原理、坑点以及如何编写健壮的自动化脚本。2. 环境搭建与核心工具选型为什么是它们工欲善其事必先利其器。在开始编写任何自动化脚本之前一个稳定、可复现的环境是基石。这里的选择看似简单但每一步都藏着新手容易踩的坑。2.1 Python 环境Anaconda 还是原生 Python对于初学者我通常推荐使用Anaconda。它是一个集成了 Python 和大量科学计算库如 NumPy, Pandas的发行版并且自带包管理工具conda。在数据分析和自动化领域conda能很好地处理包依赖冲突创建独立的虚拟环境。比如你有一个项目需要旧版本的 Selenium而另一个项目需要新版本用conda创建两个隔离环境就能完美解决。安装完成后打开 Anaconda PromptWindows或终端Mac/Linux创建一个专用于本项目的环境是个好习惯conda create -n bilibili_auto python3.9 conda activate bilibili_auto这里选择 Python 3.9 是因为它在兼容性和稳定性上经过了足够时间的考验绝大多数库都支持良好。当然3.8 或 3.10 也是可行的但尽量避免使用最新版本如 3.12 初期以免遇到第三方库尚未适配的问题。如果你更喜欢轻量级直接安装官方 Python 并使用venv创建虚拟环境也是完全没问题的。关键在于使用虚拟环境这能保证你的项目依赖不会污染系统级的 Python也方便后续的迁移和分享。2.2 Selenium 库与浏览器驱动版本匹配是生命线Selenium 本身是一个通过各类协议主要是 W3C WebDriver来控制浏览器的库。我们需要安装两个东西Selenium Python 客户端库这是我们写代码调用的接口。浏览器驱动程序WebDriver这是连接我们的代码和具体浏览器如 Chrome, Edge, Firefox的桥梁。每个浏览器版本通常对应一个特定版本的驱动。安装 Selenium 库非常简单pip install selenium难点和核心在于浏览器驱动的配置。以最常用的 Chrome 浏览器为例查看 Chrome 版本打开 Chrome在地址栏输入chrome://settings/help查看版本号例如 120.0.6099.217。下载对应版本的 ChromeDriver访问 ChromeDriver 的官方下载站点或国内镜像站。必须下载与你的 Chrome 主版本号完全一致的驱动例如 Chrome 是 120.x.x.x就找 120.x.x.x 系列的驱动。主版本号120不一致极大概率会报错。放置驱动并配置路径下载后是一个可执行文件如chromedriver.exeon Windows,chromedriveron Mac/Linux。有三种常用方式方式一推荐便于管理将驱动文件放在项目目录下或在代码中指定绝对路径。方式二系统路径将驱动文件放在系统 PATH 环境变量包含的目录中如/usr/local/bin或C:\Windows。方式三自动管理使用webdriver-manager库它可以自动下载和匹配对应版本的驱动非常适合需要频繁更新或跨环境部署的场景。安装pip install webdriver-manager。这里详细解释一下为什么版本匹配如此重要。WebDriver 协议就像浏览器和自动化脚本之间的“语言”。浏览器每次大版本更新可能会引入新的“语法”协议特性或废弃旧的“语法”。驱动版本如果与浏览器版本不匹配就像两个人在用不同版本的方言对话必然会产生误解和错误。常见的错误如“This version of ChromeDriver only supports Chrome version XX”就是由此而来。注意网络上有些教程会教人关闭浏览器的自动化检测标志如excludeSwitches: [enable-automation]或使用undetected-chromedriver这类更隐蔽的驱动。这些方法确实能绕过一些简单的检测但平台方的反爬和反自动化技术也在不断升级。对于学习目的我们使用标准驱动即可若用于生产环境测试需与开发团队确认反自动化策略。2.3 IDE 选择VSCode 与 PyCharm代码编辑器方面Visual Studio Code (VSCode)和PyCharm都是优秀的选择。VSCode轻量、免费、插件生态丰富。安装 Python 插件和 Pylance 插件后能获得很好的代码提示、调试和虚拟环境管理支持。它适合喜欢高度自定义的开发者。PyCharm (Community Edition)专为 Python 开发的 IDE开箱即用功能强大特别是其调试器和数据库工具非常出色。它更适合大型项目或团队开发。对于本项目的学习两者皆可。我个人更倾向于 VSCode因为其响应速度快与终端集成紧密方便边写代码边测试。3. 自动化脚本核心逻辑拆解模拟一个“真实”的用户假设我们的合规目标是编写一个脚本自动打开 B 站某个指定视频页面等待播放完毕然后退出。这个过程需要模拟以下关键用户行为启动浏览器、导航到网址、等待页面加载、定位播放器并触发播放、监测播放状态。下面我们分步拆解。3.1 初始化 WebDriver 与基础配置首先我们导入库并启动浏览器。这里以 Chrome 为例使用webdriver-manager来避免手动管理驱动版本的麻烦。from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time # 使用 webdriver-manager 自动管理 ChromeDriver service Service(ChromeDriverManager().install()) # 配置浏览器选项 options webdriver.ChromeOptions() # 添加一些常用选项非必须但推荐 options.add_argument(--disable-blink-featuresAutomationControlled) # 早期用于隐藏自动化特征现在作用有限 options.add_argument(--start-maximized) # 启动时最大化窗口 # options.add_argument(--headless) # 无头模式不显示图形界面。用于服务器环境但可能更容易被检测。 # 初始化驱动 driver webdriver.Chrome(serviceservice, optionsoptions)关键点解析Service对象用于管理 ChromeDriver 进程的生命周期比旧版直接webdriver.Chrome(executable_path‘path’)的方式更规范。ChromeOptions用于设置浏览器启动参数。--disable-blink-featuresAutomationControlled曾经是绕过简单检测的“银弹”但现在很多网站包括大型平台都能识别更底层的特征此参数效果已大不如前。无头模式--headless虽然节省资源但因其缺少完整的渲染环境和用户行为特征非常容易被反爬系统识别。等待策略上面代码中我们提前导入了WebDriverWait和EC这是 Selenium 自动化中最重要、最易出错的部分之一我们后面会详细讲。3.2 页面导航与元素定位精准找到“播放”按钮导航到目标页面很简单video_url https://www.bilibili.com/video/BV1xx411c7mT # 替换为目标视频BV号 driver.get(video_url)接下来是核心操作找到播放按钮并点击。这里就需要用到元素定位Locators。Selenium 提供了多种定位方式ID, Class Name, Name, Tag Name, Link Text, Partial Link Text, CSS Selector, XPath。对于 B 站播放页我们可以通过浏览器开发者工具F12来查看播放按钮的属性。通常播放按钮是一个有特定类名的div或svg元素。但直接通过类名定位可能不稳定因为前端类名可能随版本更新而变化。更稳健的做法是使用 CSS Selector 或 XPath 结合其结构和属性进行定位。例如播放按钮可能在一个类名为bpx-player-ctrl-play的 div 里。我们可以这样定位并点击try: # 显式等待等待播放按钮元素出现并可点击 play_button WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.CSS_SELECTOR, .bpx-player-ctrl-play)) ) play_button.click() print(已点击播放按钮) except Exception as e: print(f定位或点击播放按钮失败: {e}) # 可以尝试备用定位方案例如通过XPath # play_button driver.find_element(By.XPATH, //div[contains(class, bpx-player-ctrl-play)])为什么用WebDriverWait而不是time.sleep()这是新手和老手的关键区别之一。time.sleep(5)是强制等待无论页面是否加载完成都傻等5秒。如果网络慢5秒不够如果网络快就浪费了时间。WebDriverWait是显式等待它会在设定的超时时间如10秒内每隔一段时间默认0.5秒检查一次条件如“元素可点击”是否满足。一旦满足立即继续执行效率高且健壮。EC.element_to_be_clickable是等待条件之一表示等待元素不仅出现还要能被点击。3.3 模拟观看行为与状态判断点击播放只是开始。一个“真实”的观看行为还包括等待广告如果有、播放视频、可能有的弹幕加载、以及视频播放完毕的判断。1. 处理可能的片头广告B 站的部分视频有贴片广告。广告的“跳过”按钮通常在一定时间后出现。我们可以设置一个循环定期检查并点击跳过按钮。def skip_ad_if_exists(driver, timeout15): 尝试跳过广告如果存在的话 start_time time.time() while time.time() - start_time timeout: try: # 广告跳过按钮的Selector可能会变这里是一个示例 skip_ad_btn driver.find_element(By.CSS_SELECTOR, .bpx-player-ctrl-ad-skip) if skip_ad_btn.is_displayed(): skip_ad_btn.click() print(已跳过广告) return True except: pass time.sleep(1) # 每秒检查一次 print(未检测到广告或广告已自动结束) return False skip_ad_if_exists(driver)2. 判断视频是否正在播放我们可以通过检查播放器控件状态或视频当前时间是否在前进来判断。def is_video_playing(driver): 粗略判断视频是否在播放 try: # 示例获取当前播放时间元素 current_time_elem driver.find_element(By.CSS_SELECTOR, .bpx-player-ctrl-time-current) current_time_text current_time_elem.text # 如果时间不是 “0:00” 且在变化可以认为在播放 # 更准确的做法是隔几秒获取一次时间看是否变化 return current_time_text ! 0:00 and current_time_text ! --:-- except: return False3. 等待视频播放结束最朴素的方法是获取视频总时长然后time.sleep(总时长)。但这样不灵活且无法处理中途暂停、缓冲等情况。更好的方法是轮询检查播放是否结束。播放结束时播放进度条通常会到达终点或者界面会显示“重新播放”按钮。def wait_for_video_end(driver, max_wait600): # 假设视频最长10分钟 等待视频播放结束 wait_start time.time() while time.time() - wait_start max_wait: try: # 检查“重新播放”按钮是否出现 replay_button driver.find_element(By.CSS_SELECTOR, .bpx-player-ctrl-replay) if replay_button.is_displayed(): print(视频播放结束) return True except: pass # 按钮未出现继续等待 # 也可以检查进度条是否接近100% try: progress_bar driver.find_element(By.CSS_SELECTOR, .bpx-player-ctrl-progress) # 获取进度条元素的 aria-valuenow 属性或计算其宽度比例 # 这里需要根据实际页面结构解析是一个更复杂的操作 # 作为简化我们只是示例 pass except: pass time.sleep(5) # 每5秒检查一次状态 print(f等待超时{max_wait}秒可能未正常播放结束) return False wait_for_video_end(driver)3.4 会话管理与清理操作完成后务必妥善关闭浏览器释放资源。driver.quit() # 关闭浏览器并结束WebDriver会话 # 与 driver.close() 的区别close()只关闭当前标签页quit()关闭整个浏览器并停止驱动进程。4. 反自动化对抗与健壮性设计为什么你的脚本总失败如果你按上面的基础步骤写了一个脚本很可能在运行几次后就会发现失败率飙升。这是因为现代网站特别是大型平台都有复杂的反爬虫和反自动化机制。它们的目标就是区分人类用户和机器流量。下面我们来分析常见的检测点和应对策略再次强调仅用于学习如何编写更健壮的测试脚本。4.1 浏览器指纹与 WebDriver 特征检测这是最基础的检测层。普通的 Selenium WebDriver 会在浏览器navigator对象中留下webdriver属性通常为true。早期的--disable-blink-featuresAutomationControlled选项就是用来删除这个属性的但现在很多检测脚本会检查更多特征。更深入的指纹包括插件列表自动化浏览器通常插件列表与真人不同。语言和时区是否与IP地址所在地匹配。屏幕分辨率与色彩深度。Canvas 和 WebGL 指纹通过渲染图像来生成唯一标识。应对策略用于测试环境使用undetected-chromedriver这是一个修改版的 Chromedriver专门用于绕过常见的检测。它通过打补丁的方式移除或修改了许多自动化特征。注意这仍然可能被更高级的系统识别且主要用于测试不应滥用。import undetected_chromedriver as uc driver uc.Chrome()手动注入 JavaScript 修改属性在页面加载前通过execute_cdp_cmd执行 Chrome DevTools Protocol 命令来修改navigator属性。driver.execute_cdp_cmd(Page.addScriptToEvaluateOnNewDocument, { source: Object.defineProperty(navigator, webdriver, { get: () undefined }); })模拟真人浏览器环境设置合理的 User-Agent、视窗大小、时区等。options.add_argument(--window-size1920,1080) options.add_argument(--langzh-CN) # 设置User-Agent options.add_argument(user-agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...)4.2 行为模式检测鼠标、键盘与时间间隔机器操作的行为模式与人类有显著差异鼠标移动机器移动是瞬间的直线人类是带有加速度和微小抖动的曲线。点击位置机器总是精准点击元素中心人类会有偏移。输入速度机器输入是瞬间的人类有按键间隔。操作间隔机器操作间隔是固定的如每次等待2秒人类是随机且不规律的。应对策略引入随机延迟在关键操作点击、翻页前后使用time.sleep(random.uniform(1, 3))来模拟人类思考时间。模拟人类鼠标移动使用ActionChains来生成带轨迹的鼠标移动而不是直接click()。from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By element driver.find_element(By.ID, someButton) actions ActionChains(driver) # 将鼠标移动到元素上然后点击 actions.move_to_element(element).pause(0.5).click().perform()使用更高级的自动化工具如Playwright或Puppeteer它们提供了更丰富的模拟人类行为的 API例如page.mouse.move(x, y, steps10)可以让鼠标分步移动。Playwright 还能模拟更真实的触摸、滑动等移动端手势。4.3 IP 地址与账号行为关联这是平台风控最厉害的一环。如果一个 IP 地址在短时间内产生大量、规律的对同一视频的访问请求这个 IP 几乎肯定会被标记甚至封禁。同样如果一个账号只在固定时间、固定 IP 下观看视频从不进行点赞、评论、关注等互动也会被判定为异常。对于学习目的我们无法也不应去对抗这个层面。但理解其原理很重要平台的风控系统是立体的结合设备指纹、IP、账号历史行为、社交关系图等多维度数据进行实时分析。简单的换 IP代理池而不改变其他行为特征效果有限。4.4 编写健壮脚本的通用技巧即使不考虑反检测编写一个能在复杂网络环境和页面变化下稳定运行的脚本也需要技巧广泛的异常捕获与重试机制任何元素定位、点击操作都可能因为网络延迟、页面未加载完而失败。要用try...except包裹关键操作并设计重试逻辑。def click_with_retry(driver, locator, max_retries3): for i in range(max_retries): try: element WebDriverWait(driver, 10).until(EC.element_to_be_clickable(locator)) element.click() return True except Exception as e: print(f第{i1}次点击尝试失败: {e}) time.sleep(2) print(f元素 {locator} 点击失败已达最大重试次数) return False使用相对稳定的定位器优先选择id、name属性其次是用>
返回列表