☰
影刀RPA新手教程:拼多多采集全流程实战——商品数据翻页与反爬处理
2026/10/7 14:06:17 网站建设 项目流程

影刀RPA新手教程:拼多多采集全流程实战——商品数据翻页与反爬处理

我第一次做拼多多采集的时候,以为和淘宝一样直接上 XPath 就能搞定,结果流程跑了 3 页就被封了 session。后来才知道,拼多多的反爬逻辑和淘宝完全不是一个量级,class 名会定期混淆,价格字段用了"万+"之类的展示文本,直接存进去根本没法算。

这篇把拼多多采集全流程梳理一遍——从安装影刀、定位元素到翻页判断、价格清洗、写入 Excel,每个环节我都踩过坑,全写进来了。案例主线:搜索"无线耳机",采集前 10 页商品的标题、价格、销量、店铺名,存 Excel。


一、安装影刀,先把浏览器插件装好

影刀官网下载安装包,安装后第一步别急着建流程——先装浏览器插件。很多新手跳过这步,结果"获取已打开的网页对象"一直报错,以为是代码问题,折腾一下午。

插件安装路径:影刀主界面右上角→扩展→安装 Chrome 扩展。装完以后在 Chrome 扩展管理页确认一下插件已启用。如果用的是影刀自带浏览器,不需要手动装,但要注意影刀浏览器和系统 Chrome 不能同时运行,否则会冲突报错。

界面结构记三个区域就够用了:左边是指令面板(拖拽式操作),中间是流程画布,右边是变量和日志面板。编码模式才是长期用的模式,新手先熟悉拖拽,有感觉之后切编码,效率高两倍。


二、元素定位:拼多多 CSS 选择器和 XPath 的真实区别

拼多多搜索结果页,先 F12 开 DevTools,找商品列表容器。

我的实际定位路径:

商品卡片容器:

div[data-area-id="searchResultListContainer"] li.goods-list-container

商品标题(每个 li 里面):

.//div[contains(@class,'goods-title-text')]

价格(注意拼多多价格分两段:整数部分 + 小数部分):

.//span[contains(@class,'price-int')] .//span[contains(@class,'price-decimal')]

销量文本:

span.goods-sales

店铺名:

.//span[contains(@class,'store-name')]

XPath vs CSS 怎么选?拼多多页面 class 名字有些会混淆(a1b2c3这种随机串),XPath 的contains(@class,'goods-title-text')比 CSS 的精确类名更稳。但是获取相似元素列表这种批量操作,CSS 写法更简洁,用browser.find_all_by_css()传 CSS 字符串,比 XPath 少写不少代码。

正则的使用场景:价格文本采集回来是¥59.90,要提取数字用:

importre price_str="¥59.90"price=re.sub(r'[^\d.]','',price_str)# 结果 '59.90'![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/63ef7ab32af24087ba9a0a29bef13486.png#pic_center)

销量文本是"1.2万+",转成数字:

sales_text="1.2万+"if'万'insales_text:num=float(re.sub(r'[^\d.]','',sales_text.split('万')[0]))*10000else:num=float(re.sub(r'[^\d]','',sales_text))

三、变量规划:提前想好存什么

采集类流程,变量设计先于写流程。这次用到:

  • page_num:整数,当前第几页,初始值 1
  • all_data:列表,存所有商品数据(每条是字典)
  • goods_list:相似元素列表,当前页的商品卡片
  • has_next:布尔,是否有下一页
  • item:字典,单条商品数据,key:title/price/sales/shop

字典取值要注意:采集到的字段如果某个商品没有销量显示,直接item['sales']会报 KeyError。用item.get('sales', '0')更安全,给个默认值兜底。


四、流程控制:翻页判断是关键

翻页判断——不确定总页数怎么处理?

拼多多搜索结果页,总页数显示在页面底部,但更可靠的判断方式是看"下一页"按钮有没有disabled属性。

fromxbotimportweb,sleepimportrandomdefmain(args):browser=web.get_active()page_num=1all_data=[]whileTrue:# 等待商品列表加载完成browser.wait_appear('商品列表容器')# 采集当前页(见下一节)page_data=collect_current_page(browser)all_data.extend(page_data)# 判断是否有下一页next_btn_class=browser.find_by_css('button.page-next, a[aria-label="下一页"]').get_attribute('class')if'disabled'innext_btn_classorpage_num>=10:break# 点击下一页 + 随机延时(反爬核心)browser.find_by_css('button.page-next').click()sleep(random.uniform(2.5,5.0))page_num+=1returnall_data

while True+ 手动break是处理"不知道总页数"场景的标准写法。比for i in range(10)灵活,因为有时候搜索词结果不足 10 页,提前 break 比循环到找不到元素报错强多了。


五、网页自动化:采集逻辑 + 等待策略

当前页采集函数:

defcollect_current_page(browser):page_result=[]# 获取所有商品卡片goods_elements=browser.find_all_by_css('li.goods-list-container')foritemingoods_elements:try:title=item.find_by_xpath('.//div[contains(@class,"goods-title-text")]').get_text()price_int=item.find_by_xpath('.//span[contains(@class,"price-int")]').get_text()price_dec=item.find_by_xpath('.//span[contains(@class,"price-decimal")]').get_text()price=float(price_int+'.'+price_dec.strip('.'))sales=item.find_by_xpath('.//span[contains(@class,"goods-sales")]').get_text()shop=item.find_by_xpath('.//span[contains(@class,"store-name")]').get_text()page_result.append({'title':title,'price':price,'sales':sales,'shop':shop})exceptExceptionase:# 单条失败不中断整个流程continuereturnpage_result

等待策略,三种情况用三种方式:

  1. 等固定时间:sleep(3)——最简单,但不精准,浪费时间
  2. 等元素出现:browser.wait_appear('商品列表容器', timeout=15)——推荐,元素出现就继续
  3. 等页面加载完:browser.wait_load_completed()——适合跳转之后,但有些 SPA 页面这个返回 True 但 DOM 还没渲染,拼多多就是这样,用法 2 更可靠

弹窗处理:拼多多时不时弹出"领券"弹窗,在采集循环开始前加:

ifbrowser.wait_appear('关闭弹窗按钮',timeout=3):browser.find('关闭弹窗按钮').click()

timeout=3够了,超时自动返回 False,不影响主流程。


六、反爬策略:真正有效的做法

先说没用的:固定 sleep(1) 这种规律性停顿,爬虫检测系统一眼就识别出来。

真正有效的四个组合:

  1. 随机延时:每次操作后sleep(random.uniform(1.5, 4.0)),范围要够大,别用(0.5, 1.5)这种太规律的

  2. 开启模拟真人操作:影刀有内置指令"开启模拟真人操作",勾选"仿真移动鼠标"、“仿真操作停顿”,设置最小停顿 1 秒、最大停顿 3 秒。这个指令包裹住采集区间,拼多多检测鼠标轨迹的概率会降低不少

  3. 滚动模拟:每翻一页先滚动到底部再滚回来,模拟人看内容的行为

browser.scroll_to(location='bottom',behavior='smooth')sleep(random.uniform(0.8,1.5))browser.scroll_to(location='top',behavior='smooth')
  1. 监听网络请求:拼多多价格有时候走 XHR 接口,不在 DOM 里。用browser.start_monitor_network()监听,browser.get_responses(url='api/search', resource_type='XHR')拿接口数据,比解析 DOM 更稳
browser.start_monitor_network()browser.reload()responses=browser.get_responses(url='api/search',resource_type='XHR')browser.stop_monitor_network()

七、数据处理:价格清洗和销量处理

这是拼多多采集最容易忽视的环节。采回来的数据存 Excel 之前必须清洗。

价格清洗:

  • ¥59.90→ 去掉 ¥ 和非数字字符,转 float
  • 部分商品价格显示"59" 没有小数,用price_int + '.00'补全再转 float
  • 拼多多有些商品是区间价59~89,按最低价取:price_text.split('~')[0]

销量清洗:

defparse_sales(sales_text):ifnotsales_text:return0sales_text=sales_text.replace('件','').replace('已购','').strip()if'万'insales_text:returnint(float(sales_text.replace('万+','').replace('万',''))*10000)returnint(re.sub(r'\D','',sales_text)or0)

写入 Excel 注意的坑:

  1. 写入(123)这种带全角括号的数字,Excel 会自动变成-123。解决:把数字转成字符串类型再写入,或者写入前加一个空格前缀' 123'

  2. 写入 datetime 类型时间戳,用 office 模式会少 8 小时(UTC 时区问题)。解决:转成字符串str(datetime_obj)再写入,或者用 openpyxl 模式

  3. 写入大量数据(5000行+)之前先确认 Excel 进程没被占用。频繁读写 Excel 容易触发"被呼叫方拒绝接收呼叫"报错,原因是 office 进程处于编辑状态。在读写操作前后加sleep(1)能缓解,但根本方法是确保 Excel 文件是关闭状态


八、鼠标键盘辅助操作

有些拼多多搜索框需要先点击激活再输入,直接用"输入文字"指令有时会失败,因为焦点不在搜索框里。

# 先点击搜索框,再清空再输入search_input=browser.find_by_css('input[data-placeholder="搜索商品/品牌"]')search_input.click()search_input.clear()search_input.input('无线耳机')# 按 Enter 搜索fromxbotimportkeyboard keyboard.press_and_release('enter')

滚动加载商品列表(有些分类页不是翻页而是滚动加载更多):

# 每次滚动 600px,等加载for_inrange(5):browser.scroll_to(location='point',behavior='smooth',top=600*_,left=0)sleep(random.uniform(1.2,2.0))

九、平台实战:拼多多 vs 淘宝的真实区别

做过淘宝采集再做拼多多,几个地方会踩坑:

  1. 价格字段结构不一样:淘宝价格在一个完整的 span 里,class 名price;拼多多拆成整数和小数两个 span,要拼起来。直接复制淘宝的 XPath 来用,采回来全是空或者乱码

  2. 登录检测更激进:淘宝未登录也能搜索采集,拼多多搜索一定要登录,否则几页之后跳验证码。每次开流程先检测登录状态:

ifnotbrowser.wait_appear('用户头像',timeout=5):raiseException('未登录,请先手动登录拼多多')
  1. 详情页结构:拼多多商品详情页用了大量 JS 动态渲染,进入详情页后要等待主图加载完才能采集。等待方式:browser.wait_appear('商品主图', timeout=20)比wait_load_completed()可靠

  2. 搜索结果 URL 参数:拼多多搜索 URL 里search_key=无线耳机&page=2可以直接构造翻页 URL,不用点击"下一页"按钮。减少点击动作也是降低被检测概率的方式:

forpageinrange(1,11):url=f'https://www.pinduoduo.com/search_result/?search_key=无线耳机&page={page}'browser.navigate(url)browser.wait_appear('商品列表容器',timeout=20)sleep(random.uniform(2.0,4.0))

十、系统联动:采集结果发飞书通知

采集完成后自动发飞书消息,告诉自己"今天跑完了,共采了 XXX 条"。

importxbotdefnotify_feishu(count,file_path):msg=f'拼多多采集完成,共{count}条数据,文件:{file_path}'xbot.web.open('https://open.feishu.cn/open-apis/bot/v2/hook/你的webhook_token',load_timeout=10)# 或者用 HTTP 请求指令发送

用"发送 HTTP 请求"指令更稳定:POST 到飞书机器人 webhook,body 里放 JSON 格式的消息内容。这个是系统联动里最常用的通知方式,配一次以后所有流程都能复用。


十一、工程化:子流程封装和调试

流程超过 30 步就要拆子流程,否则排查问题极其痛苦。

这次拼多多采集的子流程划分:

  • init_browser:打开浏览器、登录检测、搜索关键词
  • collect_page:采集当前页数据(返回列表)
  • turn_page:翻页 + 随机等待(返回 has_next 布尔值)
  • clean_data:价格清洗 + 销量清洗(输入原始列表,返回清洗后列表)
  • write_excel:写入 Excel(输入数据列表 + 文件路径)

子流程参数传递:影刀子流程支持传入参数和返回值,用列表或字典传多个值。比如collect_page传入browser对象,返回page_data列表。

调试技巧:流程出问题不要靠猜,在疑似出错的地方加"打印日志"指令,打印当前变量值。拼多多采集常见的排查点:打印goods_elements的长度(看是不是 0),打印每条price_str的原始值(看清洗前是什么格式)。

命名规范:变量名用下划线小写goods_list,子流程名用动词开头collect_page、write_excel,别用 “子流程1”、“流程A” 这种,回头看根本不知道是干什么的。


十二、常见报错速查

报错信息原因解决方案
UIAError: 等待元素超时元素没加载出来 / XPath 写错了先手动验证 XPath 在 DevTools 里能选中;增大 timeout 到 30s
Array to String Conversion把列表直接写入 Excel 单元格用str()转字符串或','.join(list)再写入
被呼叫方拒绝接收呼叫Excel 被占用或处于编辑状态确认 Excel 关闭;写入操作前后加 sleep(1)
find_all 返回空列表class 名被混淆 / 页面未加载完用contains(@class,'...)做模糊匹配;检查是否有 iframe
price 转 float 报错价格文本含特殊字符或为空用 try-except 捕获,跳过异常条目;检查原始文本格式
翻页后数据和上一页相同翻页点击没生效,页面没刷新翻页后用wait_disappear等旧内容消失再采集

常见踩坑合集再过一遍:

  • 拼多多每次搜索完都要滚动几下,否则懒加载的商品不出来,采集到的只有前几条
  • 价格区间商品(59~89)要做 split 处理,否则转 float 直接报错
  • 不要用固定 sleep,用random.uniform(min, max),范围至少 1.5 秒差值
  • 详情页和列表页的 XPath 完全不同,要分别捕获,别混用
  • 流程跑完之后检查 Excel 行数是否和预期匹配,有时候 try-except 静默跳过了很多条

更多采集技巧可以参考 home.linyan.cloud,里面有完整的拼多多/淘宝/小红书实战案例和代码模板。

#影刀RPA #新手教程 #拼多多采集 #网页自动化 #RPA教程 #数据采集
作者:林焱

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询