使用BeautifulSoup爬取亚马逊和谷歌购物时被识别为机器人如何解决?
亚马逊/谷歌购物爬虫反封禁优化方案
现有代码的核心问题
你当前使用固定的请求头、写死的过期Cookie,且未做请求频率控制和特征打散,即便更换IP,高度统一的请求特征依然会被平台的反爬系统快速识别标记,导致重复封禁。
具体优化措施
- 请求头动态化:不要使用固定的User-Agent,可引入
fake_useragent库维护UA池,每次请求随机调取不同浏览器的UA;补全Accept、Accept-Encoding、Sec-Fetch系列等浏览器标准请求头,完全对齐真实浏览器的请求参数;不要硬编码固定Cookie,每次启动爬虫、或每爬取10-20条数据后,先请求平台首页动态获取最新Cookie使用。 - 请求频率控制:两次请求之间添加随机延迟,普通请求可设置1-5秒的随机等待时间,每爬取10-20条商品后增加30-60秒的长间隔,模拟真人浏览、翻页的停顿节奏,避免高频规律请求触发反爬。
- IP代理策略优化:优先使用高匿住宅代理,不要用容易被标记的数据中心代理;不要等IP被封禁后再更换,可设置每爬取10-30条商品就自动切换IP,切换IP的同时同步更换UA、清空旧会话的Cookie,完全打散请求特征,避免平台把不同IP的请求关联到同一个爬虫上。
- 请求行为模拟:打乱商品链接的爬取顺序,不要按照固定序号遍历;爬取过程中随机插入几次首页、分类页的跳转请求,模拟真人先逛分类再点击商品的浏览路径;遇到403、429、503等封禁状态码时,不要立刻重试,先暂停5-10分钟、更换IP和UA后再尝试,重试次数不超过3次,频繁重试会加快封禁速度。
- 工具升级(可选):如果上述优化后仍容易被封禁,可将
requests替换为undetected_chromedriver等反检测无头浏览器,这类工具会自动绕过浏览器指纹检测,请求特征和真人浏览器完全一致,更适配亚马逊、谷歌购物这类反爬规则严格的平台。
优化后代码示例
from bs4 import BeautifulSoup import requests import random import time from fake_useragent import UserAgent # 初始化UA生成器 ua = UserAgent() # 代理池请替换为你自己的可用代理地址 proxy_pool = [ "http://账号:密码@代理IP1:端口", "http://账号:密码@代理IP2:端口", # 可添加更多代理 ] def get_random_header(): """生成随机请求头""" return { "User-Agent": ua.random, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive", "Upgrade-Insecure-Requests": "1", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "none", "Sec-Fetch-User": "?1" } if __name__ == "__main__": # 示例:爬取200个商品 for page_num in range(200): # 每爬20条换一次会话、IP和Cookie if page_num % 20 == 0: session = requests.Session() current_proxy = random.choice(proxy_pool) # 先请求首页获取最新Cookie session.get( "https://www.google.it/shopping", headers=get_random_header(), proxies={"http": current_proxy, "https": current_proxy} ) # 随机延迟模拟真人停顿 time.sleep(random.uniform(1, 5)) # 发起商品页请求,url替换为你要爬的商品地址 response = session.get( url, headers=get_random_header(), proxies={"http": current_proxy, "https": current_proxy} ) # 触发封禁则暂停10分钟后再继续 if response.status_code in (403, 429, 503): time.sleep(600) continue # 解析逻辑 soup = BeautifulSoup(response.content, "lxml") # 后续数据提取逻辑...
内容的提问来源于stack exchange,提问作者CastoldiG
相关产品推荐
相关产品推荐

