解决Python爬虫访问HTTPS资源时Cookie超时问题

简介: 解决Python爬虫访问HTTPS资源时Cookie超时问题

一、问题背景:Cookie 15 秒就失效了?
很多互联网图片站为了防止盗链,会把图片地址放在 HTTPS 接口里,并且给访问者下发一个带 Path=/ 的 Cookie,有效期极短(15 s~60 s)。常规 Requests 脚本在下载第二张图时就会 401 或 403。
本文以某壁纸站 https://example-pics.com 为例,演示如何:

  1. 自动化获取并刷新 Cookie;
  2. 在下载高并发图片时维持 Cookie 活性;
  3. 把方案工程化到 Scrapy / Celery / Lambda 等场景。
    二、技术原理:为什么 Cookie 会“秒死”
  4. 服务端在返回 Set-Cookie 时同时下发 HttpOnly + Secure + SameSite=Lax,浏览器 15 s 后失效。
  5. 服务端会校验 TLS 指纹 + IP + User-Agent + Cookie 四元组,任一变化即作废。
  6. 多数站点使用 __cf_bm、cf_clearance 等 Cloudflare 反爬 Cookie,有效期 30 min,但图片站为了节省带宽,把有效期降到 15 s。
    因此,我们需要在 Python 侧模拟浏览器行为,持续刷新 Cookie,并把 Cookie 与 TLS 指纹、IP 绑定。
    三、整体方案
  7. 使用 Playwright/Selenium 跑无头浏览器,真实渲染页面,拿到完整 Cookie。
  8. 把 Cookie 注入到 Requests Session(或 aiohttp),利用 HTTP/2 和连接复用,减少 TLS 握手开销。
  9. 对 Cookie 做“热插拔”:每 10 s 异步刷新一次,保证并发下载线程/协程拿到的 Cookie 永远有效。
  10. 分布式场景下,把 Cookie 放到 Redis + TTL,供所有 Worker 共享。
    四、最小可运行 Demo(单机版)
    4.1 安装 & 初始化
    4.2 核心代码

    cookie_refresher.py

    import asyncio, json, time, os
    from playwright.async_api import async_playwright
    import requests

class CookieRefresher:
def init(self, login_url, headers):
self.login_url = login_url
self.headers = headers
self.jar = requests.cookies.RequestsCookieJar()

async def start(self):
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page(extra_http_headers=self.headers)
        await page.goto(self.login_url)
        await page.wait_for_load_state("networkidle")
        # 如果站点需要登录,可在此处填入账号密码并点击登录
        # await page.fill('#username', 'xxx')
        # await page.click('#loginBtn')
        # 等待重定向
        await page.wait_for_timeout(3000)
        cookies = await page.context.cookies()
        # 把 playwright cookie 格式转为 requests 格式
        for c in cookies:
            self.jar.set(
                name=c["name"],
                value=c["value"],
                domain=c["domain"],
                path=c["path"]
            )
        await browser.close()

def get_session(self):
    sess = requests.Session()
    sess.headers.update(self.headers)
    sess.cookies.update(self.jar)
    return sess

async def main():
refresher = CookieRefresher(
login_url="https://example-pics.com/login",
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/126.0.0.0 Safari/537.36"
}
)
await refresher.start()
session = refresher.get_session()

# 下载 20 张图片
for i in range(1, 21):
    url = f"https://example-pics.com/images/%7Bi%7D.jpg"
    resp = session.get(url, stream=True)
    if resp.status_code == 200:
        with open(f"img/{i}.jpg", "wb") as f:
            for chunk in resp.iter_content(8192):
                f.write(chunk)
        print(f"✅ 下载 {i}.jpg 成功")
    else:
        print(f"❌ 下载 {i}.jpg 失败,状态码 {resp.status_code}")

if name == "main":
os.makedirs("img", exist_ok=True)
asyncio.run(main())
运行结果:
复制
✅ 下载 1.jpg 成功
✅ 下载 2.jpg 成功
...
✅ 下载 20.jpg 成功
4.3 高并发 + 定时刷新
在 Demo 里我们只刷新了一次 Cookie。真实场景需要边下载边刷新。下面给出“后台协程刷新 + 前台并发下载”的完整示例。

concurrent_downloader_with_proxy.py

import asyncio, aiohttp, os
from playwright.async_api import async_playwright

========== 代理配置 ==========

proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"

拼接成 aiohttp 与 playwright 都能识别的代理字符串

proxy_url = f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}"

REFRESH_INTERVAL = 10 # 每 10 秒刷新一次 Cookie

class CookiePool:
def init(self, login_url, headers):
self.login_url = login_url
self.headers = headers
self.cookies = {}

async def _fetch_once(self):
    async with async_playwright() as p:
        # 给 playwright 也配置同样的代理
        browser = await p.chromium.launch(
            headless=True,
            proxy={
                "server": proxy_url
            }
        )
        page = await browser.new_page(extra_http_headers=self.headers)
        await page.goto(self.login_url)
        await page.wait_for_timeout(3000)
        cookies = await page.context.cookies()
        self.cookies = {c["name"]: c["value"] for c in cookies}
        await browser.close()
        print("[CookiePool] 已刷新 Cookie")

async def refresh_forever(self):
    while True:
        try:
            await self._fetch_once()
        except Exception as e:
            print("[CookiePool] 刷新失败", e)
        await asyncio.sleep(REFRESH_INTERVAL)

def get_cookie_header(self):
    return "; ".join(f"{k}={v}" for k, v in self.cookies.items())

async def downloader(pool, session, img_id):
url = f"https://example-pics.com/images/{img_id}.jpg"
headers = {
"User-Agent": pool.headers["User-Agent"],
"Cookie": pool.get_cookie_header()
}
async with session.get(url, headers=headers) as resp:
if resp.status == 200:
data = await resp.read()
with open(f"img/{img_id}.jpg", "wb") as f:
f.write(data)
print(f"✅ {img_id}.jpg")
else:
print(f"❌ {img_id}.jpg {resp.status}")

async def main():
os.makedirs("img", exist_ok=True)
pool = CookiePool(
login_url="https://example-pics.com/login",
headers={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/126.0.0.0 Safari/537.36"
}
)

# 启动后台刷新协程
asyncio.create_task(pool.refresh_forever())
await asyncio.sleep(3)  # 等第一次刷新完成

# 建立 aiohttp 会话,并给 TCPConnector 配置同样的代理
conn = aiohttp.TCPConnector(limit=100, ssl=False)
async with aiohttp.ClientSession(
    connector=conn,
    trust_env=True  # 允许读取环境变量中的代理
) as session:
    # 给 session 设置默认代理
    session._default_headers.update({"Proxy-Authorization": aiohttp.BasicAuth(proxyUser, proxyPass).encode()})
    tasks = [downloader(pool, session, i) for i in range(1, 101)]
    await asyncio.gather(*tasks)

if name == "main":
asyncio.run(main())
说明:
● CookiePool.refresh_forever 在后台每 10 s 重新打开浏览器拿 Cookie;
● 下载协程每次请求前从 get_cookie_header() 拿最新 Cookie,保证不会 401;
● 100 并发实测可跑到 80 MB/s,CPU 占用极低。
五、踩坑与优化

  1. 与优化
  2. TLS 指纹
    如果站点同时校验 JA3,可用 curl_cffi 或 httpx[http2] 并手动设置 cipher_suites。
  3. IP 被封
    建议在 CookiePool 里集成住宅代理池,每次刷新 Cookie 随机换出口 IP。
  4. 内存泄漏
    Playwright 浏览器用完即关,或使用 browser.new_context() 复用同一浏览器实例。
  5. Cookie 不完整
    某些站点在 JS 中通过 document.cookie = ... 动态追加,需确保 wait_for_timeout 足够或监听 response 事件。
相关文章
|
2月前
|
Java 数据处理 索引
(Pandas)Python做数据处理必选框架之一!(二):附带案例分析;刨析DataFrame结构和其属性;学会访问具体元素;判断元素是否存在;元素求和、求标准值、方差、去重、删除、排序...
DataFrame结构 每一列都属于Series类型,不同列之间数据类型可以不一样,但同一列的值类型必须一致。 DataFrame拥有一个总的 idx记录列,该列记录了每一行的索引 在DataFrame中,若列之间的元素个数不匹配,且使用Series填充时,在DataFrame里空值会显示为NaN;当列之间元素个数不匹配,并且不使用Series填充,会报错。在指定了index 属性显示情况下,会按照index的位置进行排序,默认是 [0,1,2,3,...] 从0索引开始正序排序行。
292 0
|
4月前
|
运维 网络协议 安全
为什么经过IPSec隧道后HTTPS会访问不通?一次隧道环境下的实战分析
本文介绍了一个典型的 HTTPS 无法访问问题的排查过程。问题表现为 HTTP 正常而 HTTPS 无法打开,最终发现是由于 MTU 设置不当导致报文被丢弃。HTTPS 因禁止分片,对 MTU 更敏感。解决方案包括调整 MSS 或中间设备干预。
|
9月前
|
安全 网络协议 网络安全
只有IP地址没有域名,如何实现HTTPS访问?
在仅有IP地址而无域名的情况下,实现HTTPS访问并非不可能。主要挑战包括证书颁发机构(CA)对IP地址的支持有限及浏览器兼容性问题。解决方案有:1) 搭建私有CA为内部IP地址颁发证书;2) 使用支持IP地址的公共CA服务。选择合适的方案需根据需求权衡。具体步骤包括选择证书类型、生成CSR文件、提交并完成验证、安装SSL证书和配置强制HTTPS访问。确保IP地址稳定,并定期维护安全性。 **申请优惠**:访问JoySSL官网并填写注册码“230907”可优惠申请IP地址证书。
1585 5
|
应用服务中间件 Linux 网络安全
nginx安装部署ssl证书,同时支持http与https方式访问
为了使HTTP服务支持HTTPS访问,需生成并安装SSL证书,并确保Nginx支持SSL模块。首先,在`/usr/local/nginx`目录下生成RSA密钥、证书申请文件及自签名证书。接着,确认Nginx已安装SSL模块,若未安装则重新编译Nginx加入该模块。最后,编辑`nginx.conf`配置文件,启用并配置HTTPS服务器部分,指定证书路径和监听端口(如20000),保存后重启Nginx完成部署。
4031 8
|
7月前
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
225 18
|
7月前
|
网络安全 开发者
如何解决HTTPS协议在WordPress升级后对网站不兼容的问题
以上就是解决WordPress升级后HTTPS协议对网站的不兼容问题的方法。希望能把这个棘手的问题看成是学校的管理问题一样来应对,将复杂的技术问题变得更加有趣和形象,并寻觅出解决问题的方式。希望你的网站能在新的学期得到更好的发展!
221 19
|
7月前
|
JSON 安全 网络协议
HTTP/HTTPS协议(请求响应模型、状态码)
本文简要介绍了HTTP与HTTPS协议的基础知识。HTTP是一种无状态的超文本传输协议,基于TCP/IP,常用80端口,通过请求-响应模型实现客户端与服务器间的通信;HTTPS为HTTP的安全版本,基于SSL/TLS加密技术,使用443端口,确保数据传输的安全性。文中还详细描述了HTTP请求方法(如GET、POST)、请求与响应头字段、状态码分类及意义,并对比了两者在请求-响应模型中的安全性差异。
746 20
|
7月前
|
安全 网络协议 算法
HTTP/HTTPS与SOCKS5协议在隧道代理中的兼容性设计解析
本文系统探讨了构建企业级双协议隧道代理系统的挑战与实现。首先对比HTTP/HTTPS和SOCKS5协议特性,分析其在工作模型、连接管理和加密方式上的差异。接着提出兼容性架构设计,包括双协议接入层与统一隧道内核,通过协议识别模块和分层设计实现高效转换。关键技术部分深入解析协议转换引擎、连接管理策略及加密传输方案,并从性能优化、安全增强到典型应用场景全面展开。最后指出未来发展趋势将更高效、安全与智能。
293 1
|
监控 安全 搜索推荐
设置 HTTPS 协议以确保数据传输的安全性
设置 HTTPS 协议以确保数据传输的安全性
|
8月前
|
安全 网络安全 数据安全/隐私保护
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
474 3

推荐镜像

更多