影刀RPA 网页详情页批量采集:列表到详情跳转
作者:林焱
什么情况用什么
采集列表页只能拿到标题和摘要,完整信息在详情页里——商品详情、文章正文、公司信息等。需要在影刀RPA中先采集列表页的链接,再逐个打开详情页提取深度数据。这个"列表→详情"的两级采集是网页数据采集最核心的模式。
适用场景:电商商品完整信息采集、新闻文章正文采集、企业黄页详情采集、招聘网站职位详情。
怎么做
完整流程设计
1. 【打开网页】→ 列表页URL 2. 【提取相似元素】→ 提取列表页所有详情链接 3. 【循环遍历】→ 逐个打开详情页 4. 【等待元素出现】→ 等待详情页加载 5. 【提取数据】→ 提取详情页字段 6. [video(video-oniAuA6S-1784737862161)(type-csdn)(url-https://live.csdn.net/v/embed/525010)(image-https://v-blog.csdnimg.cn/asset/f4faa587144cb7070f19e8b36813806b/cover/Cover0.jpg)(title-店群矩阵自动化突破运营极限!)] 7. 【翻页】→ 回到列表页翻下一页 8. 循环1-6直到所有页采完第一步:采集列表页链接
frombs4importBeautifulSoupimportrequestsdefget_detail_links(list_url,headers=None):"""从列表页提取所有详情页链接"""ifheadersisNone:headers={'User-Agent':'Mozilla/5.0...'}response=requests.get(list_url,headers=headers,timeout=10)soup=BeautifulSoup(response.text,'html.parser')links=[]# 根据实际网站调整选择器items=soup.select('.list-item a.title, .product-item a, .article-title a')foriteminitems:href=item.get('href','')ifnothref:continue# 处理相对路径ifhref.startswith('//'):href='https:'+hrefelifhref.startswith('/'):href=requests.compat.urljoin(list_url,href)# 去重ifhrefnotinlinks:links.append(href)returnlinks# 采集多页链接defget_all_links(base_url,max_pages=10):"""采集所有页的详情链接"""all_links=[]forpageinrange(1,max_pages+1):url=f"{base_url}?page={page}"links=get_detail_links(url)ifnotlinks:print(f"第{page}页无链接,停止")breakall_links.extend(links)print(f"第{page}页获取{len(links)}个链接,累计{len(all_links)}个")returnall_links第二步:采集详情页数据
importtimedefscrape_detail_page(url,headers=None):"""采集单个详情页"""ifheadersisNone:headers={'User-Agent':'Mozilla/5.0...'}try:response=requests.get(url,headers=headers,timeout=15)response.encoding=response.apparent_encoding soup=BeautifulSoup(response.text,'html.parser')data={'来源URL':url}# 标题data['标题']=safe_text(soup.select_one('h1.title, h1, .detail-title'))# 价格data['价格']=safe_text(soup.select_one('.price, .detail-price'))# 正文/描述data['描述']=safe_text(soup.select_one('.description, .detail-content, .content'))# 规格specs=soup.select('.spec-item, .attr-item')forspecinspecs:label=safe_text(spec.select_one('.label, .name'))value=safe_text(spec.select_one('.value, .text'))iflabel:data[label]=value# 图片images=soup.select('.detail-image img, .gallery img')data['图片列表']='|'.join([img.get('src','')forimginimages])returndataexceptExceptionase:return{'来源URL':url,'错误':str(e)}defsafe_text(element):"""安全提取文本"""ifelement:returnelement.get_text(strip=True)return''第三步:批量采集+保存
importpandasaspdimportosdefbatch_scrape_details(base_url,output_file,max_pages=10,delay=1):"""批量采集详情页"""# 1. 采集所有链接print("开始采集列表页链接...")all_links=get_all_links(base_url,max_pages)print(f"共获取{len(all_links)}个详情链接")# 2. 逐个采集详情all_data=[]fori,linkinenumerate(all_links,1):print(f"正在采集第{i}/{len(all_links)}个:{link}")data=scrape_detail_page(link)all_data.append(data)# 每采集10条保存一次(防止中途崩溃丢数据)ifi%10==0:temp_df=pd.DataFrame(all_data)temp_df.to_excel(output_file,index=False)print(f" 已保存{len(all_data)}条")# 延迟,避免被封time.sleep(delay)# 3. 最终保存df=pd.DataFrame(all_data)df.to_excel(output_file,index=False)print(f"采集完成,共{len(df)}条,保存到{output_file}")returndf# 使用batch_scrape_details(base_url="https://example.com/products",output_file=r"C:\Data\product_details.xlsx",max_pages=5,delay=1.5)在影刀RPA中的完整流程
【设置变量】all_data = [] 【循环】页码 1 到 10 【打开网页】列表页URL + 页码 【等待元素出现】.list-item 【提取相似元素数据】→ 获取所有详情链接 【循环】遍历每个链接 【打开新标签页】详情页URL 【等待元素出现】.detail-title 【提取数据】标题、价格、描述等 【关闭标签页】 【等待】1秒 【结束循环】 【点击元素】下一页按钮 【结束循环】 【写入Excel文件】all_data断点续采
defresume_scrape(link_file,output_file,delay=1):"""断点续采:跳过已采集的链接"""# 读取所有链接withopen(link_file,'r')asf:all_links=[line.strip()forlineinfifline.strip()]# 读取已采集的链接scraped_urls=set()ifos.path.exists(output_file):existing_df=pd.read_excel(output_file)scraped_urls=set(existing_df['来源URL'].tolist())# 只采集未完成的pending=[lforlinall_linksiflnotinscraped_urls]print(f"总共{len(all_links)}个,已完成{len(scraped_urls)}个,剩余{len(pending)}个")all_data=[]ifscraped_urls:all_data=pd.read_excel(output_file).to_dict('records')fori,linkinenumerate(pending,1):data=scrape_detail_page(link)all_data.append(data)ifi%5==0:pd.DataFrame(all_data).to_excel(output_file,index=False)print(f"已保存{len(all_data)}条")time.sleep(delay)pd.DataFrame(all_data).to_excel(output_file,index=False)returnlen(all_data)有什么坑
坑1:详情页结构不统一
同样是详情页,有的有价格有的没有,有的多了个推荐区——采集代码报错中断:
# 解决:所有提取都用safe_text,返回空字符串而非报错defsafe_text(element):try:returnelement.get_text(strip=True)ifelementelse''except:return''# 字段缺失时给默认值data['价格']=safe_text(soup.select_one('.price'))or'未知'坑2:详情页打开失败
某些链接404或超时,导致整个采集中断:
temu店群自动化报活动案例
# 解决:try-except包裹,记录失败继续下一个forlinkinall_links:try:data=scrape_detail_page(link)all_data.append(data)exceptrequests.Timeout:print(f"超时:{link}")all_data.append({'来源URL':link,'错误':'超时'})exceptrequests.ConnectionError:print(f"连接失败:{link}")all_data.append({'来源URL':link,'错误':'连接失败'})time.sleep(5)# 等待网络恢复exceptExceptionase:print(f"错误:{link}-{e}")all_data.append({'来源URL':link,'错误':str(e)})坑3:详情页需要登录
列表页不需要登录,但详情页需要登录才能看完整内容:
# 解决:在影刀中用浏览器模式采集# 先【执行登录流程】保持登录态# 然后用【打开网页】+【提取数据】而非requests# 或者在requests中带Cookiesession=requests.Session()# 先登录获取Cookielogin_data={'username':'xxx','password':'xxx'}session.post('https://example.com/login',data=login_data)# 后续请求自动带Cookieresponse=session.get(detail_url)坑4:详情页数据是AJAX加载
页面打开后内容是空的,数据通过JS异步加载:
# 解决1:找到API接口直接请求# F12 → Network → XHR → 找到数据接口api_url=f"https://example.com/api/product/{product_id}"response=requests.get(api_url,headers=headers)data=response.json()# 解决2:用影刀浏览器+等待# 【打开网页】→ 【等待元素出现】.detail-content(超时10秒)→ 【提取数据】坑5:采集速度太快被封IP
# 解决:随机延迟 + 代理IP轮换importrandom# 随机延迟delay=random.uniform(1,3)# 1-3秒随机time.sleep(delay)# 代理IP轮换proxy_pool=['http://ip1:port','http://ip2:port',]forlinkinall_links:proxy={'http':random.choice(proxy_pool)}try:response=requests.get(link,headers=headers,proxies=proxy,timeout=10)except:# 代理失败,用本机IPresponse=requests.get(link,headers=headers,timeout=10)