简介:一套基于影刀RPA的京东达人视频自动化采集项目源码,面向具备基础RPA操作能力或自动化流程开发经验的读者,也适用于需要批量获取京东视频素材的运营人员。项目通过模拟浏览器访问达人视频首页,结合页面元素解析提取视频地址,完成批量下载并按既定目录保存,同时将视频标题、发布时间、作者等字段提取整理,写入Excel表格,实现采集、存储、记录一体化流程,避免大量重复手工操作。压缩包共8个文件,包含Python主程序、依赖说明txt、CSV数据样例、HTML可视化界面以及3个实操演示视频,整体仅约9KB,体量轻、结构清晰。目前已有119人学习下载。除了可直接运行的采集代码,还附带演示视频与界面文件,可帮助快速理解影刀RPA中流程编排、元素定位及数据落地技巧;CSV样例直观呈现输出格式,便于扩展字段或改造为多页面批量监控工具。代码内部注释了核心步骤,适合作为RPA自动化开发的实战参考,也可用于二次开发或日常运营中的视频采集任务。项目虽小巧,但完整覆盖从页面分析、数据提取到落盘存储的主要链路,是理解桌面自动化从入门到落地的实用样例。
1. 影刀RPA京东视频采集到底解决什么问题
做电商运营的人常碰到一件枯燥事:手里拿着几百个京东商品链接,要挨个打开详情页,把主图视频下载下来,要么做竞品素材归档,要么给自家商品拍摄找参考。人工操作一个链接约一分钟,点开页面、等加载、找播放按钮、等缓冲、右键另存为,几百个链接就是五六个小时,还容易漏视频、存错文件、手滑关掉页面。影刀RPA京东视频采集这个方向,就是把这套重复动作拆成“浏览器操作 + 元素识别 + 文件保存”的自动化流程,让机器按同一套逻辑反复执行。它的价值不是“能采集视频”这个结果,而是把采集从一次性手工活变成可复用、可审计、可批量跑的脚本资产。适合谁?适合每天要处理几十上百个商品视频的电商运营、数据采集岗,也适合刚接触RPA、想找一个有明确业务场景练手的人。先说明白:这类自动化只应在你拥有合法访问权限、用于合规业务场景时使用,不要用它去突破平台规则或批量抓取受保护的内容。
2. 采集链路拆解:从商品页到视频文件,影刀要替你做哪几件事
2.1 视频藏在页面哪里:主图区的播放按钮和背后的真实地址
京东商品详情页的视频,绝大多数不在页面底部的详情描述区,而在顶部主图轮播区域。常见形态是:第一张主图旁边或右上角有一个“播放”图标,点击后会在原位置弹出一个视频播放器。这里第一个容易踩的认知坑是:你以为视频是一个mp4文件直接写在页面源码里的,实际上京东的商品视频是动态加载的。打开页面时,视频封面图会先显示,但真正的视频资源要等播放器初始化后才从接口拉取,而且地址往往带签名参数,直接复制src属性拿到的可能是一段blob:协议地址,或者一个几百毫秒就过期的临时链接。
所以采集的第一步不是“找视频”,而是“确认视频从哪个接口来”。常见做法是:用影刀打开商品页,定位到主图区的视频封面元素,执行点击,触发播放器加载,再通过浏览器开发者工具观察网络请求,找到返回视频真实地址的那个接口。在影刀里,你可以用“获取元素属性”功能拿到视频节点的src,但更稳妥的是捕获播放器加载时的数据接口,从响应文本里解析出视频直链。这个思路决定了下面所有流程怎么写:你不是在模拟“另存为”,你是在模拟“播放器拿到视频地址然后自己下载”。
2.2 最小闭环流程:搜索或跳转、进详情、触播放、取地址、下载保存
把整个采集拆成最小闭环,一共五步:
第一步,准备输入数据。通常是一张 Excel 表,第一列放商品链接或商品 ID(SKU)。第二步,让影刀打开浏览器,逐个访问链接,等待详情页主图区加载完成。第三步,定位视频封面元素并点击,等待播放器出现,同时准备捕获视频地址。第四步,从播放器节点或接口响应里提取视频直链。第五步,使用影刀内置的”下载文件“指令,或者调用系统下载器,把视频保存到本地目录,文件名用 SKU 加时间戳命名。
这五步看起来简单,实际运行时的顺序依赖很强。比如必须先等待播放器真正初始化,否则拿不到地址;必须先判断页面里到底有没有视频,因为部分商品只有图片没有视频。所以最小闭环跑通后,紧接着要做的是给每一步加状态判断和异常分支。下面第三部分就按这个闭环一步步写可落地的配置和代码。
2.3 影刀的核心指令选型:识图点击还是元素绑定
动手前先选对指令,这决定了整个脚本的稳定上限。影刀里操作网页有两种主流方式:一种是“元素操作”,直接绑定页面上的按钮、图片、输入框等控件,优点是定位精准、速度快,缺点是页面改版后绑定会失效;另一种是“图像操作”,按截图匹配位置点击,优点是抗改版能力强,缺点是对分辨率、缩放比例敏感,慢而且容易误点。
我的建议:第一版用元素操作,因为京东详情页结构相对稳定,主图区播放按钮有固定 class 特征。只有在元素绑定失败、页面部分区域是 canvas 渲染或动态蒙层时,才用图像操作兜底。具体到影刀里,你可以用“网页元素”功能里的“采集元素”去抓播放按钮,也可以直接在 Python 代码块里写选择器。下面第三部分的代码就按元素操作来写,因为可复制性最强。
3. 把京东视频采集拆成可复现的流程:关键步骤与参数设置
3.1 打开商品详情页的稳定写法:等待策略与链接规范化
第一步不是访问链接,而是规范化链接。很多表里的链接带着渠道参数,比如?utm_source=xxx,这些参数不影响访问,但会影响后续文件命名里对商品 ID 的提取。所以我一般先做一步链接清洗:从原始链接里用正则提取skuId或数字 ID,再拼接成干净的详情页地址。这样后续日志和数据表里只保留规范化的 ID,排错时一眼能看出是哪个商品。
import re raw_url = "https://item.jd.com/100012345678.html?utm_source=baidu" # 提取数字ID,京东详情页URL格式基本是 /{id}.html match = re.search(r"/(\d{6,})\.html", raw_url) if not match: raise ValueError(f"无法从链接中提取商品ID: {raw_url}") sku_id = match.group(1) clean_url = f"https://item.jd.com/{sku_id}.html" print(clean_url)逻辑说明:先用正则从原始链接里找到 6 位以上的数字 ID,然后重新拼接。这样做的原因是后续影刀循环里每个商品只保留一个sku_id,既能避免重复采集,也能在保存视频时用 ID 做文件名。参数说明:\d{6,}表示至少 6 位数字,京东的 SKU 通常 8 位以上;如果你遇到链接里没有.html后缀而是纯参数形式,需要额外处理,这种情况多半是来自活动页跳转,建议先人工核对。
打开页面的代码块在影刀里建议直接用“打开网页”指令,但为了统一异常处理,我用 Python 代码块写更可控:
from 影刀内置模块 import web # 伪代码示意,实际用影刀提供的浏览器对象 browser = web.create_chrome_session() browser.get(clean_url) # 关键:等主图区域出现,而不是只等页面标题 browser.wait_for_selector(".J-magic-area", timeout=10)逻辑说明:wait_for_selector等待的是主图区域的选择器,这个区域出现说明详情页核心结构已加载。很多新手只等“页面加载完成”事件,但京东页面是异步渲染的,页面框架出来后主图可能还在转圈。参数说明:timeout设 10 秒,如果页面慢,可以调大到 15,但超过 20 秒还加载不出来多半是网络或风控问题,后面第五章会讲。
3.2 定位视频封面并触发播放:三类选择器与点击时机
京东主图区的视频封面,通常出现在第一张主图的左侧或上方,是一个小播放图标。这个图标的元素特征不固定,所以我一般用“包含文本”的方式定位,或者直接找video标签的父级节点。更稳的做法是等视频封面元素出现后再点击,而不是进入页面立刻点。
# 方式一:通过 class 关键字定位播放按钮(常见为 play 相关 class) play_btn = browser.wait_for_selector( "[class*='play'], [class*='Play'], [data-type='video']", timeout=8 ) play_btn.click() # 方式二:如果按钮是覆盖在主图上的透明蒙层,直接点击视频区域 video_cover = browser.wait_for_selector(".pic-video", timeout=8) video_cover.click()逻辑说明:方式一用属性包含匹配,扩大命中范围;方式二更适合按钮被图片蒙层覆盖的情况,直接点击封面区域就等同于触发播放。实际项目中两个方式都试一下,哪个在你的目标页面上命中率好用哪个。参数说明:[class*='play']是 CSS 选择器,匹配 class 里含 play 的元素;如果你用影刀的可视化元素绑定,可以直接从页面上拾取按钮,但不建议完全依赖,因为商品页有时候主图视频不止一个,通过 class 匹配可以顺手把所有候选节点都找出来。
触发播放后,播放器会创建video标签。此时不要急着拿地址,因为视频可能还在缓冲。你需要等待视频的readyState变成可播放状态,或者直接等video标签的src属性非空。这一步在影刀里可以用“等待元素属性”指令,也可以写在代码块里:
# 等待 video 标签出现且 src 属性非空 video_el = browser.wait_for_selector("video", timeout=8) # 影刀代码块里获取元素属性值 video_src = video_el.get_attribute("src") if not video_src: # 如果 src 为空,说明视频地址在 data 属性里 video_src = video_el.get_attribute("data-src") or video_el.get_attribute("data-url") print(video_src)逻辑说明:src为空时常见原因是播放器把真实地址存在>import requests headers = { "User-Agent": browser.get_user_agent(), "Referer": clean_url, # 防盗链关键 "Cookie": browser.get_cookie_string() } resp = requests.get(video_src, headers=headers, timeout=20) if resp.status_code == 200 and len(resp.content) > 1024: # 用 sku_id 和视频序号命名 filename = f"{sku_id}_video.mp4" with open(f"D:/jd_videos/{filename}", "wb") as f: f.write(resp.content) else: print(f"下载失败: {sku_id}, status={resp.status_code}, size={len(resp.content)}")
逻辑说明:这里最关键的是把浏览器会话里的User-Agent、Referer、Cookie都带上。京东的视频直链通常做了防盗链校验,不加Referer或者Cookie过期都会导致返回 403。resp.content长度判断是为了过滤掉错误页,有些时候服务器返回 200 但内容是一段 HTML 提示,而不是视频流。参数说明:timeout=20是请求超时,下载大视频时可以调大到 60;保存路径D:/jd_videos/需要提前创建,影刀指令里可以用“创建目录”来做,但 Python 代码块里建议先os.makedirs。
如果是blob:协议地址,requests请求会直接失败。这种情况常见处理是换一个思路:不解析视频地址,而是用影刀的键盘鼠标操作,在播放器上右键“视频另存为”,但弹窗不好控制。更实用的办法是回退到播放器接口,在网页里执行 JS 获取播放器的currentSrc:
# 在影刀代码块里执行 JS,拿到播放器实际媒体地址 real_src = browser.execute_script( "document.querySelector('video').currentSrc || document.querySelector('video').src" )逻辑说明:currentSrc是浏览器解析后的真实媒体地址,多数情况下比src属性更可靠。拿到这个地址后再走前面的requests下载流程。参数说明:执行 JS 前必须确认video标签存在,且播放器已经触发,否则会拿到空值。
4. 批量场景下的数据管理与异常处理
4.1 数据表设计:输入列、状态列、结果列的配置
单条采集跑通后,批量只是加一层循环。但循环不能盲目跑,你得让每一次执行有记录、可回溯。我习惯用一张 Excel 表同时充当输入和输出,表头至少包含这几列:原始链接、清洗后链接、SKU ID、是否有视频、视频直链、下载状态、本地文件名、错误信息、采集时间。
在影刀里,读取 Excel 用“打开 Excel / 读取列”指令,写入用“写入单元格”。也可以在代码块里用openpyxl直接操作,但可视化指令更直观。下面是建议的字段设计:
| 字段 | 类型 | 说明 |
|---|---|---|
| 原始链接 | 文本 | 从表里直接带过来的原始 URL |
| SKU ID | 文本 | 正则提取后的商品 ID,去重和命名依赖它 |
| 是否有视频 | 布尔 | 页面元素是否找到播放按钮 |
| 视频直链 | 文本 | 实际请求的 mp4 地址,方便人工复核 |
| 下载状态 | 枚举 | 成功 / 失败 / 跳过 |
| 错误信息 | 文本 | 失败的简短原因,如“播放器超时” |
| 本地文件名 | 文本 | 实际保存的文件名,便于映射 |
| 采集时间 | 时间 | 每次循环的结束时间 |
这个表设计的好处是:如果某个商品下载失败,你不需要重跑全量,只需要把失败行筛出来,下次单独跑一个“失败重试”的流程。这一步看似琐碎,实际能帮你省掉大量重复劳动。
4.2 循环里的频率控制:随机延时与失败退避
批量跑的时候最常见的翻车是操作太快触发风控。影刀本身自动化点击的频率如果很稳定,服务器端比较容易识别。我一般会在每个商品之间加一个随机延时,而不是固定等待。这个随机延时的区间可以结合商品页加载时间动态设置。
import time import random # 每个商品处理完成后,随机休息 2~5 秒 time.sleep(random.uniform(2, 5)) # 如果失败,退避时间按失败次数递增 def backoff(retry_count): return min(10, 2 ** retry_count) + random.uniform(0, 2)逻辑说明:random.uniform(2, 5)产生 2 到 5 秒之间的随机浮点数,避免每次间隔一模一样。失败退避用的是指数退避思想,第一次失败等 2 秒,第二次等 4 秒,最多等 10 秒加上随机抖动,给网络和风控一个恢复窗口。参数说明:如果采集量不大(几十个),固定 3 秒也够用;如果每天跑几千个链接,建议把基础间隔提高到 5 秒以上,并且尽量避免在高峰期集中跑。
4.3 断点续采:把已完成 SKU 从任务表里剔掉
批量中最怕跑到一半程序崩了,或者某次手动关闭浏览器,下次要从头再来。解决办法是每次循环开始前,先检查当前 SKU 是否已经在“下载状态”列里标记为“成功”,如果是就直接跳过。这个逻辑写在循环开头,比写在结尾更有效,因为它能防止半途异常导致的重跑。
from openpyxl import load_workbook wb = load_workbook("jd_tasks.xlsx") ws = wb.active for row in range(2, ws.max_row + 1): sku_id = ws.cell(row, 3).value status = ws.cell(row, 6).value if status == "成功": continue # 执行该行的采集流程 result = process_one_sku(sku_id) # 写入状态、文件名、错误信息 ws.cell(row, 6).value = result["status"] ws.cell(row, 7).value = result["message"] ws.cell(row, 8).value = result["local_file"] ws.cell(row, 9).value = time.strftime("%Y-%m-%d %H:%M:%S") wb.save("jd_tasks.xlsx")逻辑说明:每次处理完一行立刻保存,而不是全部跑完再一次性保存。这样做的好处是即使中途崩了,已保存的结果不会丢,重新运行时会自动跳过成功行。row从 2 开始是因为第 1 行是表头。参数说明:ws.cell(row, 6)对应第六列“下载状态”,如果你实际表头列顺序不同,需要调整列索引。另外,wb.save每行都调用会比较慢,如果你追求速度,可以每 10 行保存一次,但风险是崩溃时丢最近 10 行结果,自己权衡。
5. 京东视频采集常见问题与避坑指南
5.1 页面一直转圈,元素等待超时
现象:循环跑到某几个商品时,wait_for_selector一直等到超时,日志提示主图区域未出现。原因:京东部分商品页带强交互脚本,或者该商品已下架,页面只显示“商品已下架”提示,没有主图区域。解决:不要一超时就报错退出,先读取页面标题或主体文本,判断是否是已下架页面。我一般会在搞定链接后先拿一个标记元素,比如页面标题里的“商品已下架”关键词,命中就直接把状态标记为“已下架”,跳过采集。
5.2 视频是懒加载的,脚本点不到播放按钮
现象:明明页面上有视频封面,但脚本用元素选择器点击时提示元素不可交互。原因:主图区域的视频封面是懒加载的,页面滚动到主图区后,播放按钮才真正渲染到 DOM 里。解决:先滚动页面让主图区域进入视口,再用影刀“滚动到元素”指令,然后稍微等 0.5 秒再点击。不要一进入页面就立刻找按钮,给懒加载留一点渲染时间。
5.3 视频地址带签名,下载请求返回 403
现象:浏览器里能正常播放的视频,用requests下载时返回 403 Forbidden。原因:京东视频直链的 URL 里带有签名参数,而且签名绑定了当时的Referer和Cookie,跨会话请求会被拒。解决:确保下载请求头里的Referer是商品详情页地址,Cookie取自当前同一个浏览器会话,不要用独立的requests.Session重新建连接。另外,签名有时效,从拿到地址到发起下载尽量控制在几秒内,不要先存到中间表再下载。
5.4 登录态过期,详情页跳转到登录墙
现象:跑了几十个商品后,突然发现打开的页面变成了登录框,所有元素定位失败。原因:京东网页版对未登录用户的部分操作会触发登录校验,尤其是在频繁访问、携带非标准 User-Agent 时。解决:在流程开头先做一个“是否已登录”的校验,比如查找页面右上角是否有“你好,请登录”文本,如果有就暂停并提示人工扫码登录。同时注意不要用无头浏览器,无头模式更容易触发风控。
5.5 下载下来的视频打不开,文件只有几 KB
现象:下载状态显示成功,文件大小只有 3KB,双击播放器提示文件损坏。原因:下载的不是视频流,而是服务器返回的错误页或重定向提示,通常是requests请求时没有跟随重定向,或者拿到的地址本身是 m3u8 索引文件而不是 mp4。解决:下载后加一个文件头校验,MP4 文件的前几个字节通常是ftyp,代码里检查一下再决定是否保存。如果是 m3u8 地址,那就不是单文件下载,需要解析切片,这种情况建议改走播放器接口拿 mp4。
6. 验证采集结果的三个技巧与进阶方向
第一个技巧:校验文件完整性。下载完成后不要只看文件大小,要读取文件头确认是 MP4 格式。用 Python 一行代码就能做:
with open(file_path, "rb") as f: header = f.read(4) valid = header == b"\x00\x00\x00\x18ftyp" or header[:4] == b"ftyp"如果不是ftyp开头,大概率是错误页或空文件,直接标记失败并删除,避免混进素材库。第二个技巧:视频去重。同一个 SKU 可能有多个视频,或者不同 SKU 共用同一个视频源。这时可以记录视频直链的 MD5,作为第二列字段存到表格里,下次遇到相同 MD5 直接跳过存储,节省硬盘空间。第三个技巧:断点重试时不要重下已成功文件,而是先按“文件名是否存在且文件头有效”判断,如果本地文件已经存在且有效,就直接把状态改成成功,这一步能省很多重复下载。
再往下进阶,可以考虑把采集流程做成定时任务,每天增量抓取指定类目的新品视频。做法是维护一张 SKU 清单,每天早上跑一次,把新增商品的视频下载到按日期分文件夹的目录里。如果采集量很大,建议把“浏览器操作”和“视频下载”拆成两个脚本:一个脚本只抓视频地址并写入队列表,另一个脚本用多线程去下载队列里的地址。这样即使浏览器端被风控限速,下载端也不会闲着,整体吞吐量能提升不少。
这里分享一个我的习惯:任何采集脚本,第一版跑通后不要急着扩展功能,先把日志做好。我会在每次循环里输出当前 SKU、耗时、结果状态,并把日志写入文件。这样出了问题看日志就能定位,不用靠猜。这个习惯帮我避免了很多次半夜爬起来看脚本卡在哪个页面的血泪时刻。做采集方向的自动化,“稳定”永远比“功能多”重要,你永远不知道线上页面哪一天改版,提前做好校验和记录,就是给自己留后悔药。希望这篇笔记对你有用。
本文还有配套的精品资源,点击获取