Cookie 模拟登录 3 大误区:从 17k.com 案例看 requests 与 Selenium 选择

📅 2026/7/11 23:21:26 ✍️ 编辑团队 👁️ 阅读次数
Cookie 模拟登录 3 大误区:从 17k.com 案例看 requests 与 Selenium 选择
Cookie 模拟登录 3 大误区从 17k.com 案例看 requests 与 Selenium 选择在数据采集和自动化测试领域模拟登录是绕不开的技术门槛。许多开发者在使用 Python 进行网页自动化时往往会在 Cookie 处理环节踩坑。本文将以 17k.com 小说网站为例深度剖析三种主流技术方案的优劣并提供可落地的解决方案。1. 模拟登录的核心机制解析HTTP 协议本身是无状态的网站通过 Cookie 维持用户会话。当用户首次登录时服务器会在响应头中设置 Set-Cookie 字段浏览器将这些信息保存并在后续请求中自动携带。模拟登录的本质就是复现这个过程。关键验证点登录请求是否触发重定向302 状态码响应头是否包含 Set-Cookie 字段后续请求是否携带正确的 Cookie 头以 17k.com 为例其登录流程存在以下特点采用标准的表单提交POST /ck/user/login登录成功后返回 JSON 格式响应需要处理多个关联域名passport.17k.com 和 user.17k.com的 Cookie2. 技术方案对比与选型2.1 三种实现方式对比特性直接 requestsrequests.SessionSelenium执行速度⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️内存占用低中高反爬绕过能力❌✅✅✅JS 渲染支持❌❌✅✅验证码处理困难困难可行适用场景简单接口标准网站复杂SPA应用2.2 决策流程图graph TD A[目标网站特性] -- B{依赖JS渲染?} B --|是| C[Selenium方案] B --|否| D{有验证码?} D --|是| C D --|否| E[requests.Session] E -- F[简单接口?] F --|是| G[直接requests] F --|否| E注意当遇到动态参数如 _xsrf或加密参数时优先考虑 Selenium 方案3. 实战代码实现3.1 requests.Session 方案import requests from urllib.parse import urljoin BASE_URL https://passport.17k.com/ LOGIN_URL urljoin(BASE_URL, /ck/user/login) BOOKSHELF_URL https://user.17k.com/ck/author/shelf def login_with_session(username, password): session requests.Session() session.headers.update({ Origin: https://passport.17k.com, Referer: https://passport.17k.com/login/ }) payload { loginName: username, password: password, remember: on } resp session.post(LOGIN_URL, datapayload) if resp.json().get(status) ! 1: raise ValueError(登录失败) # 获取书架数据 shelf_resp session.get(BOOKSHELF_URL) return shelf_resp.json()关键点必须设置正确的 Origin 和 Referer保持同一个 Session 对象发起连续请求处理跨域 Cookiedomain.17k.com3.2 Selenium 混合方案from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import requests def hybrid_login(username, password): # 第一阶段Selenium 获取Cookie driver webdriver.Chrome() driver.get(https://passport.17k.com/login/) WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.NAME, loginName)) ).send_keys(username) driver.find_element(By.NAME, password).send_keys(password) driver.find_element(By.CSS_SELECTOR, button[typesubmit]).click() # 等待登录完成 WebDriverWait(driver, 10).until( EC.url_contains(user.17k.com) ) # 提取Cookie cookies {c[name]: c[value] for c in driver.get_cookies()} driver.quit() # 第二阶段requests 持续使用 session requests.Session() for name, value in cookies.items(): session.cookies.set(name, value) shelf_resp session.get(BOOKSHELF_URL) return shelf_resp.json()优势可处理图形验证码需人工干预自动执行页面 JavaScript获取完整浏览器环境 Cookie4. 常见误区与解决方案误区一Cookie 失效问题现象登录成功但后续请求返回 403Cookie 存活时间极短解决方案# 添加心跳保活机制 def keep_alive(session): ping_url https://user.17k.com/ck/user/check_login session.get(ping_url, timeout3) # 在关键请求前调用 keep_alive(session)误区二Header 校验不足必要请求头headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), X-Requested-With: XMLHttpRequest, Sec-Fetch-Dest: empty, Sec-Fetch-Mode: cors }误区三SSL 验证问题解决方案# 禁用SSL验证不推荐生产环境使用 session requests.Session() session.verify False # 或指定证书路径 session.verify /path/to/cert.pem5. 高级技巧与优化5.1 Cookie 持久化方案import pickle import os def save_cookies(session, filename): with open(filename, wb) as f: pickle.dump(session.cookies, f) def load_cookies(filename): if os.path.exists(filename): with open(filename, rb) as f: return pickle.load(f) return None # 使用示例 session requests.Session() if cookies : load_cookies(17k.cookies): session.cookies.update(cookies) else: login_with_session(username, password) save_cookies(session, 17k.cookies)5.2 请求重试机制from tenacity import retry, stop_after_attempt, wait_exponential retry(stopstop_after_attempt(3), waitwait_exponential(multiplier1, min2, max10)) def safe_request(url, session): resp session.get(url) resp.raise_for_status() if 请登录 in resp.text: raise ValueError(Session expired) return resp5.3 性能优化对比测试数据100次请求直接 requests平均 1.2sSession平均 0.8sSelenium平均 32.7s内存占用requests.Session约 15MBSelenium约 280MB在实际项目中建议根据目标网站的防护等级选择合适方案。对于 17k.com 这类中等防护网站requests.Session 配合适当的请求头设置即可满足需求而面对更复杂的反爬机制时Selenium 仍是可靠选择。