现代 Web 爬虫技术:Session + Cookie 认证的模拟登录
1. 前言
很多刚入门爬虫的同学可能遇到过这种情况:直接爬取公开内容没问题,但想爬自己账号的订单、收藏夹或者会员专属内容时,要么直接弹出 401 Unauthorized,要么爬回来的是“未登录跳转页”的空壳?
别慌!Session + Cookie 认证 作为最“古老”但至今仍广泛应用在中小网站、内部系统、部分早期大厂产品的认证方式,是解决这类问题最快、最稳的方案之一。本文会结合 案例网站 一步步讲原理、上代码、给避坑指南,新手也能快速复刻!
2. 技术准备
先把环境搭好,工具库都是 Python 爬虫圈的“国民级”存在,安装也超简单:
环境要求
- Python 3.8+(低版本 requests 可能有兼容性,建议 3.10+ 更顺手)
- 浏览器(推荐 Chrome/Edge,调试方便)
- 不需要自己手动下载 Chromedriver 哦!
webdriver-manager 会帮你搞定
一键安装依赖
pip install requests selenium webdriver-manager beautifulsoup4
# 加个 bs4 是为了后面验证登录成功时更直观,不然光打印 URL 不够过瘾
3. 案例网站分析
实战用的是 崔庆才老师的模拟登录站 https://login2.scrape.center/ —— 没有验证码、JS 逻辑简单,特别适合练手,但完全还原了真实 Session+Cookie 登录的流程。
3.1 网站特点速览
- 采用传统 MVC 架构,后端渲染页面
- 纯 Session + Cookie 认证,没有 OAuth、JWT 这些花活
- 登录成功后会跳转到
https://login2.scrape.center/(首页,展示电影列表)
3.2 真实登录流程拆解(F12 必看!)
爬虫开发最核心的步骤永远是分析流程,别一上来就写代码!按下面步骤打开 Chrome DevTools(F12 或右键→检查):
- 打开 Network 面板,勾选「Preserve log」(保留重定向日志,这个很重要!)
- 手动输入账号密码
admin/admin,点击登录
- 筛选 Network 面板的请求类型为「Doc」(只看文档请求,更清晰)
你会看到 3 个关键请求,对应完整的登录认证链:
再点进第 1 个 POST 请求的「Response Headers」,你会看到这行关键信息:
Set-Cookie: sessionid=abc123xyz; Path=/; HttpOnly
这就是后端“发”给浏览器的「门禁卡」——Session ID,之后所有请求浏览器都会自动把它夹在 Cookie 里带过去。
4. 模拟登录的3种实现方式
4.1 入门踩坑版:手动管理 Cookie(❌ 不推荐)
很多小白第一次写会这么做:单独发 POST 请求拿 Cookie,再把 Cookie 塞到 GET 请求里——虽然能跑,但每次请求都是独立的“新浏览器窗口”,管理起来超级麻烦,Cookie 还容易丢。
import requests
# 定义常量(好习惯!别把账号密码写死在代码里,生产环境可以用环境变量)
LOGIN_URL = "https://login2.scrape.center/login"
INDEX_URL = "https://login2.scrape.center/"
USERNAME = "admin"
PASSWORD = "admin"
# 1. 单独发 POST 请求,禁止自动重定向(不然拿不到 Set-Cookie)
login_resp = requests.post(
LOGIN_URL,
data={"username": USERNAME, "password": PASSWORD},
allow_redirects=False
)
# 2. 手动提取 Response 里的 Cookie
cookies = login_resp.cookies
# 3. 单独发 GET 请求,手动塞 Cookie
index_resp = requests.get(INDEX_URL, cookies=cookies)
# 简单验证:看看页面里有没有“欢迎回来,admin”(用 bs4 查)
from bs4 import BeautifulSoup
soup = BeautifulSoup(index_resp.text, "html.parser")
print(soup.find("h2", class_="mb-3")) # 成功的话会打印 <h2>欢迎回来,admin</h2>
4.2 主流推荐版:用 requests.Session(✅ 必学)
requests 库早就帮我们封装好了 Session 会话对象——它就像一个“持久化的浏览器窗口”,会自动管理所有 Cookie、请求头、代理等,登录一次之后后续所有请求都能直接用!
import requests
from bs4 import BeautifulSoup
LOGIN_URL = "https://login2.scrape.center/login"
INDEX_URL = "https://login2.scrape.center/"
USERNAME = "admin"
PASSWORD = "admin"
# 1. 创建一个 Session 会话对象
session = requests.Session()
# 2. (可选但推荐)先加个通用的 User-Agent,模拟真实浏览器,避免被反爬
session.headers.update({
"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"
})
# 3. 用 Session 发 POST 登录请求(不需要禁止重定向,Session 会自动处理)
login_resp = session.post(
LOGIN_URL,
data={"username": USERNAME, "password": PASSWORD}
)
# 简单验证登录状态码(POST 重定向后的首页状态码应该是 200)
print("登录后首页状态码:", login_resp.status_code)
# 4. 用同一个 Session 发后续所有请求(自动携带 Cookie,太爽了!)
index_resp = session.get(INDEX_URL)
soup = BeautifulSoup(index_resp.text, "html.parser")
print(soup.find("h2", class_="mb-3"))
4.3 复杂场景版:Selenium 拿 Cookie + Requests 爬取(✅ 进阶必备)
如果遇到有滑块验证码、图形验证码、指纹识别、复杂 JS 加密的网站,纯用 requests 很难搞定——这时候可以先用 Selenium 模拟真实用户的操作完成登录,拿到有效 Cookie 后,再丢给 requests 去高效爬取(Selenium 打开浏览器慢,requests 是纯 HTTP 请求,快几十倍)。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import requests
from bs4 import BeautifulSoup
import time
LOGIN_URL = "https://login2.scrape.center/login"
INDEX_URL = "https://login2.scrape.center/"
USERNAME = "admin"
PASSWORD = "admin"
# -------------------------- Selenium 模拟登录 + 拿 Cookie --------------------------
# 1. 初始化 Chrome 浏览器(webdriver-manager 自动下载对应版本的驱动)
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
# (可选)窗口最大化,避免元素找不到
driver.maximize_window()
try:
# 2. 打开登录页
driver.get(LOGIN_URL)
# (必加!新手常犯的错:页面还没加载完就找元素,会报错 NoSuchElementException)
time.sleep(1)
# 3. 模拟输入账号密码、点击登录
driver.find_element(By.CSS_SELECTOR, 'input[name="username"]').send_keys(USERNAME)
driver.find_element(By.CSS_SELECTOR, 'input[name="password"]').send_keys(PASSWORD)
driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click()
# 等跳转完成
time.sleep(2)
# 4. 验证是否登录成功(如果当前 URL 是首页,说明成功)
if driver.current_url == INDEX_URL:
print("Selenium 模拟登录成功!")
# 5. 获取登录后的所有 Cookie
selenium_cookies = driver.get_cookies()
else:
print("Selenium 模拟登录失败!")
selenium_cookies = []
finally:
# 6. 关闭浏览器(用完就关,节省资源)
driver.quit()
# -------------------------- Requests 拿 Cookie 继续爬取 --------------------------
if selenium_cookies:
session = requests.Session()
session.headers.update({
"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"
})
# 把 Selenium 的 Cookie 逐个塞到 requests 的 Session 里
for cookie in selenium_cookies:
session.cookies.set(
name=cookie["name"],
value=cookie["value"],
domain=cookie["domain"],
path=cookie["path"]
)
# 验证 + 爬取首页前 3 个电影标题
index_resp = session.get(INDEX_URL)
soup = BeautifulSoup(index_resp.text, "html.parser")
print("首页前3个电影:")
for i, movie in enumerate(soup.find_all("h5", class_="card-title"), 1):
print(f"{i}. {movie.text.strip()}")
5. 避坑指南 + 最佳实践
5.1 Cookie 管理小技巧
- 持久化存储 Cookie:如果要长期爬,可以把有效 Cookie 存到
JSON 文件或数据库里,下次直接用,不用每次都登录
- Cookie 池:如果爬取频率高,容易被封账号,可以注册多个小号,维护一个 Cookie 池,每次请求随机换一个
- 定期检测 Cookie 有效性:很多网站的 Session ID 有时效性(比如 24 小时),可以每次爬之前先请求一个“只有登录才能访问的小接口”,如果返回 401 就重新登录
5.2 反反爬虫的小细节
哪怕案例网站没有反爬,真实网站大概率有,这几点一定要注意:
- User-Agent 不能丢:不要用 requests 默认的
python-requests/x.x.x,太明显了
- Referer 要跟上:比如从首页跳转到详情页,Referer 要设成首页的 URL
- 加随机延迟:每次请求之间加
time.sleep(random.uniform(1, 3)),模拟真实用户的操作节奏
- 不要爬太快太狠:哪怕加了延迟,也不要一天爬几十万条,会给服务器造成压力,也容易被封 IP
6. 总结
Session + Cookie 认证虽然是“老古董”,但胜在简单、稳定、易调试,至今仍是很多场景的首选认证方式。新手爬取需要登录的网站时,优先学 requests.Session;遇到复杂验证码或 JS 加密,再考虑 Selenium 拿 Cookie + Requests 爬取 的组合拳。
扩展阅读: