
影刀RPA 网页翻页全攻略页码与加载更多作者林焱什么情况用什么采集列表数据时一页只有20条总共几百上千条需要翻页。不同网站的翻页方式不同——有传统的页码点击翻页、有加载更多按钮、有无限滚动。在影刀RPA里需要根据不同翻页方式选择对应策略并且要正确判断什么时候该停止。适用场景电商商品列表翻页采集、新闻列表分页采集、搜索结果分页采集、任何需要翻页的列表数据采集。怎么做方式一页码翻页拼多多店群自动化报活动上架【打开网页】→ 第1页URL 【循环】 【提取数据】→ 当前页数据 【判断元素是否存在】→ 下一页按钮 存在 → 【点击元素】下一页 → 【等待页面加载】 不存在 → 【退出循环】影刀RPA中的操作# 用影刀可视化指令的伪流程# 1. 【打开网页】 https://example.com/list?page1# 2. 【循环】while True# 3. 【提取相似元素数据】→ 当前页列表数据# 4. 【判断元素是否存在】→ .next-page:not(.disabled)# 5. True → 【点击元素】→ .next-page# 6. False → break# 7. 【等待元素出现】→ .list-item 确保新页加载完用Python实现importrequestsfrombs4importBeautifulSoupimporttimedefscrape_with_pagination(base_url,max_pages50):页码翻页采集all_data[]forpageinrange(1,max_pages1):urlf{base_url}?page{page}responserequests.get(url,headersheaders,timeout10)soupBeautifulSoup(response.text,html.parser)# 提取当前页数据itemssoup.select(.list-item)ifnotitems:print(f第{page}页无数据停止)breakforiteminitems:data{标题:safe_text(item.select_one(.title)),价格:safe_text(item.select_one(.price)),}all_data.append(data)print(f第{page}页{len(items)}条累计{len(all_data)}条)# 检查是否有下一页next_btnsoup.select_one(.next-page:not(.disabled))ifnotnext_btn:print(没有下一页停止)breaktime.sleep(1)returnall_data方式二加载更多按钮defscrape_with_load_more(url,max_clicks50):加载更多按钮翻页# 在影刀中需要用浏览器自动化# 因为加载更多是JS动态追加内容all_data[]forclick_countinrange(max_clicks):# 1. 提取当前页面数据# 影刀指令【提取相似元素数据】current_dataextract_current_page_data()all_data.extend(current_data)# 2. 查找加载更多按钮# 影刀指令【判断元素是否存在】load_morecheck_element_exists(.load-more-btn)ifnotload_more:print(f第{click_count1}次无加载更多按钮停止)break# 3. 点击加载更多# 影刀指令【点击元素】→ .load-more-btnclick_element(.load-more-btn)# 4. 等待新内容加载# 影刀指令【等待元素出现】→ .list-item:last-childtime.sleep(2)# 5. 检查是否有新数据new_dataextract_current_page_data()iflen(new_data)len(all_data):print(f第{click_count1}次无新数据停止)breakprint(f第{click_count1}次点击累计{len(all_data)}条)returnall_data方式三无限滚动defscrape_infinite_scroll(url,max_scrolls100):无限滚动采集all_data[]last_count0no_change_count0forscroll_numinrange(max_scrolls):# 1. 滚动到底部# 影刀指令【执行JavaScript代码】js_scrollwindow.scrollTo(0, document.body.scrollHeight);execute_js(js_scroll)# 2. 等待加载time.sleep(2)# 3. 提取当前数据current_dataextract_current_page_data()all_datacurrent_data# 页面上所有数据# 4. 检查是否有新数据iflen(all_data)last_count:no_change_count1ifno_change_count3:print(f连续3次无新数据停止)breakelse:no_change_count0last_countlen(all_data)print(f第{scroll_num1}次滚动共{len(all_data)}条)returnall_data通用翻页框架importpandasaspdimporttimeimportrandomclassWebScraper:通用翻页采集框架def__init__(self,namescraper):self.namename self.all_data[]self.output_fileNonedefscrape_page(self,page_num):采集单页子类实现raiseNotImplementedErrordefhas_next_page(self,page_num):判断是否有下一页子类实现raiseNotImplementedErrordefrun(self,max_pages50,delay_range(1,3),output_fileNone):执行采集self.output_fileoutput_fileforpageinrange(1,max_pages1):try:dataself.scrape_page(page)ifnotdata:print(f[{self.name}] 第{page}页无数据停止)breakself.all_data.extend(data)print(f[{self.name}] 第{page}页:{len(data)}条, 累计{len(self.all_data)}条)# 定期保存ifoutput_fileandpage%50:self.save(output_file)ifnotself.has_next_page(page):print(f[{self.name}] 没有下一页停止)break# 随机延迟delayrandom.uniform(*delay_range)time.sleep(delay)exceptExceptionase:print(f[{self.name}] 第{page}页出错:{e})# 出错后等待更久time.sleep(5)continueifoutput_file:self.save(output_file)returnself.all_datadefsave(self,filepath):保存数据dfpd.DataFrame(self.all_data)df.to_excel(filepath,indexFalse)print(f[{self.name}] 已保存{len(df)}条到{filepath})# 使用示例classProductScraper(WebScraper):def__init__(self,base_url):super().__init__(ProductScraper)self.base_urlbase_url self.headers{User-Agent:Mozilla/5.0...}defscrape_page(self,page_num):urlf{self.base_url}?page{page_num}responserequests.get(url,headersself.headers,timeout10)soupBeautifulSoup(response.text,html.parser)itemssoup.select(.product-item)return[{标题:safe_text(i.select_one(.title)),价格:safe_text(i.select_one(.price))}foriinitems]defhas_next_page(self,page_num):urlf{self.base_url}?page{page_num1}responserequests.get(url,headersself.headers,timeout10)soupBeautifulSoup(response.text,html.parser)returnbool(soup.select(.product-item))# 使用scraperProductScraper(https://example.com/products)scraper.run(max_pages20,output_filerC:\Data\products.xlsx)有什么坑坑1翻页后数据重复TEMU店群矩阵自动化运营核价报活动点击下一页后URL变了但页面内容没刷新导致采集到重复数据# 解决等待URL变化等待新内容出现# 影刀中# 【点击元素】下一页# 【等待URL变化】→ 等待URL包含?page2# 【等待元素出现】→ .list-item# 【等待】1秒额外等待渲染# 或者用数据去重seen_idsset()foritemindata:item_iditem.get(ID)ifitem_idanditem_idinseen_ids:continueseen_ids.add(item_id)all_data.append(item)坑2下一页按钮disabled状态判断错误# 问题下一页按钮一直存在但最后一页时class变成disabled# 如果只判断按钮是否存在永远不停# 错误ifsoup.select_one(.next-page):# 一直为Truecontinue# 死循环# 正确检查disabled状态next_btnsoup.select_one(.next-page:not(.disabled))# 或next_btnsoup.select_one(.next-page)ifnext_btnanddisablednotinnext_btn.get(class,[]):continueelse:break坑3AJAX翻页URL不变有些网站翻页不改变URL只是JS动态加载# 解决找到AJAX接口# F12 → Network → 点击下一页 → 找到XHR请求# 直接请求APIapi_urlfhttps://example.com/api/list?page{page}size20responserequests.get(api_url,headersheaders)dataresponse.json()itemsdata.get(data,data.get(list,[]))坑4翻页速度太快被限制# 解决随机延迟 模拟人类行为importrandom# 随机1-3秒延迟delayrandom.uniform(1,3)time.sleep(delay)# 偶尔长暂停模拟人离开ifrandom.random()0.1:# 10%概率long_pauserandom.uniform(5,10)print(f模拟休息{long_pause:.1f}秒...)time.sleep(long_pause)坑5总页数未知导致无法预估进度# 解决先查看是否有总页数信息total_pagessoup.select_one(.total-pages)iftotal_pages:totalint(total_pages.get_text(stripTrue))print(f总共{total}页)else:print(总页数未知将持续采集直到无数据)# 或者先快速请求最后一页# 很多网站URL支持?page99999自动跳转到最后一页test_urlf{base_url}?page99999responserequests.get(test_url)# 从返回的URL或页面中获取真实总页数