网页抓取时如何确保多请求持续返回Response 200?
解决方案
你的问题核心在于每次请求都新建cloudscraper实例、UA过于生硬、请求间隔太短,导致被Cloudflare的反爬机制识别并限制。以下是能稳定获取200响应的调整方案:
关键优化点
- 复用会话实例:不要每次调用
make_soup都新建cloudscraper,复用同一个会话能保留Cookie和会话状态,更接近真实用户行为。 - 使用真实浏览器UA:替换掉自定义的
ScraperBot/1.0,改用当前主流浏览器的UA字符串,降低被识别为爬虫的概率。 - 延长随机延迟范围:把1-5秒的间隔调整为3-10秒,模拟真人浏览的节奏。
- 添加重试机制:遇到403时自动重试,配合更长的等待时间避免频繁触发限制。
修改后的代码
from bs4 import BeautifulSoup import cloudscraper from time import sleep from random import randint from requests.exceptions import RequestException url = 'https://www.ralphlauren.co.uk/en/men/clothing/1020?webcat=men-clothing' # 全局复用cloudscraper实例,配置真实浏览器UA scraper = cloudscraper.create_scraper( delay=10, browser={ 'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36', 'platform': 'windows', 'mobile': False } ) def make_soup(url, max_retries=3): retries = 0 while retries < max_retries: try: sleep(randint(3, 10)) # 延长随机延迟 req = scraper.get(url) if req.status_code == 200: print(req) return BeautifulSoup(req.text, 'lxml') elif req.status_code == 403: retries += 1 print(f"收到403,正在重试第{retries}次...") sleep(randint(5, 15)) # 重试前延长等待时间 else: print(f"请求失败,状态码:{req.status_code}") break except RequestException as e: print(f"请求出错:{e}") retries += 1 sleep(randint(5, 15)) print(f"重试{max_retries}次后仍失败,返回None") return None # 获取列表页 browsing_page_soup = make_soup(url) if browsing_page_soup: page_links = [i.get('href') for i in browsing_page_soup.select('a.thumb-link')] product_pages_soup = [] for link in page_links: full_url = 'https://www.ralphlauren.co.uk' + link soup = make_soup(full_url) if soup: product_pages_soup.append(soup)
额外建议
- 如果仍出现403,建议使用代理IP池,每次请求切换不同IP,避免单一IP被频繁限制。
- 不要一次性请求所有商品页,可分批次处理,比如每请求5个页面就暂停30秒左右,进一步降低反爬触发概率。
内容的提问来源于stack exchange,提问作者user13174343
相关产品推荐
相关产品推荐

