Python Requests爬取Tesco匈牙利网店啤酒价格的Cookie自动处理问题
问题描述
我长期用Python的requests库获取Tesco匈牙利网店(https://bevasarlas.tesco.hu/groceries/hu-HU/shop/alkohol/sor-cider/all)的啤酒页面HTML,再用Scrapy提取价格数据。之前只需要在请求头里传User-Agent就能正常拿到响应,但本周网站新增反爬机制后,请求直接没响应。现在只有手动从浏览器复制Cookie到请求头里,脚本才能正常运行。但脚本需要每日自动执行,没法每次手动更新Cookie,想请教怎么实现Cookie的自动生成和更新?
当前使用代码
import requests from scrapy import Selector headers = { 'Cookie': '这里是手动从浏览器复制的完整Cookie字符串', 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36' } page_url = 'https://bevasarlas.tesco.hu/groceries/hu-HU/shop/alkohol/sor-cider/all' html = requests.get(url = page_url, headers = headers, timeout = 10).content sel = Selector(text = html) scraped_data = sel.xpath('//li[contains(@class, "product-list--list-item")]') card = scraped_data[0] name = card.xpath('.//span[@class="styled__Text-sc-1xbujuz-1 ldbwMG beans-link__text"]/text()').extract()
解决方案
1. 用无头浏览器模拟真实请求获取Cookie
网站新增的反爬大概率检测了浏览器环境(比如JS渲染、自动化指纹),手动复制的Cookie依赖浏览器会话,用无头浏览器可以自动完成会话初始化并获取有效Cookie,是目前最靠谱的方案:
示例(Playwright)
Playwright比Selenium更轻量,支持无头模式,能自动处理JS渲染和Cookie生成:
from playwright.sync_api import sync_playwright import requests from scrapy import Selector def get_tesco_cookies(): with sync_playwright() as p: # 启动无头浏览器,禁用自动化标识避免被检测 browser = p.chromium.launch( headless=True, args=['--disable-blink-features=AutomationControlled'] ) page = browser.new_page( user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36' ) page.goto('https://bevasarlas.tesco.hu/groceries/hu-HU/shop/alkohol/sor-cider/all') # 等待商品列表加载完成,确保会话初始化完成 page.wait_for_selector('li.product-list--list-item', timeout=15000) # 获取当前页面的所有Cookie cookies = page.context.cookies() # 转换成requests能直接用的Cookie字符串格式 cookie_str = '; '.join([f"{c['name']}={c['value']}" for c in cookies]) browser.close() return cookie_str # 主逻辑 headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36' } page_url = 'https://bevasarlas.tesco.hu/groceries/hu-HU/shop/alkohol/sor-cider/all' # 获取最新有效Cookie headers['Cookie'] = get_tesco_cookies() html = requests.get(url=page_url, headers=headers, timeout=10).content sel = Selector(text=html) scraped_data = sel.xpath('//li[contains(@class, "product-list--list-item")]') if scraped_data: card = scraped_data[0] name = card.xpath('.//span[@class="styled__Text-sc-1xbujuz-1 ldbwMG beans-link__text"]/text()').extract() print(name)
注意事项
- 首次运行需要安装Playwright的Chromium浏览器:执行
playwright install chromium - 如果还是被检测,可以尝试添加随机鼠标移动、滚动等模拟人类操作的代码
2. 用requests.Session维持会话自动更新Cookie(仅适用于无JS验证场景)
如果网站的Cookie是通过初始请求的Set-Cookie响应头生成的,不需要JS验证,可以尝试用Session对象自动处理Cookie的获取和更新:
import requests from scrapy import Selector # 创建Session对象,自动处理Cookie session = requests.Session() session.headers.update({ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36', 'Referer': 'https://bevasarlas.tesco.hu/groceries/hu-HU/' }) # 先访问网站首页,获取初始Cookie session.get('https://bevasarlas.tesco.hu/groceries/hu-HU/', timeout=10) # 再请求目标页面,Session会自动带上之前获取的Cookie page_url = 'https://bevasarlas.tesco.hu/groceries/hu-HU/shop/alkohol/sor-cider/all' response = session.get(page_url, timeout=10) html = response.content sel = Selector(text=html) scraped_data = sel.xpath('//li[contains(@class, "product-list--list-item")]') if scraped_data: card = scraped_data[0] name = card.xpath('.//span[@class="styled__Text-sc-1xbujuz-1 ldbwMG beans-link__text"]/text()').extract() print(name)
不过这种方法大概率无效,因为网站新增的反爬通常依赖JS验证,Session无法处理JS渲染的内容。
3. 额外反爬绕过技巧
- 加入随机延迟:每次请求前用
time.sleep(random.uniform(1,3))等待1-3秒,模拟人类操作间隔 - 随机切换User-Agent:维护一个常见User-Agent列表,每次请求随机选一个,避免固定标识被识别
- 添加Referer头:模拟从网站首页跳转至目标页面的请求流程
内容的提问来源于stack exchange,提问作者Mate P
相关产品推荐
相关产品推荐

