很多网站的内容需要登录才能看到,比如知乎的关注动态、微博的关注列表、电商平台的订单信息。这一篇就讲怎么用 Python 搞定模拟登录。
一、Cookie 与 Session 基本原理
HTTP 为什么需要它们?
HTTP 是无状态的------服务器记不住你之前来过。Cookie 和 Session 就是为了解决"记住我是谁"这个问题。
第一次请求:POST /login → 用户名+密码
服务器验证通过,返回 Set-Cookie: session_id=abc123
第二次请求:GET /profile → 浏览器自动带上 Cookie: session_id=abc123
服务器一看 Session ID 就知道你是谁
核心流程:
- 登录成功后,服务器返回 Cookie
- 后续请求带着 Cookie,服务器就能识别身份
- Cookie 过期或被清除,就需要重新登录
二、requests.Session------自动管理 Cookie
requests.Session 会自动保存和发送 Cookie,比手动处理省事很多。
python
import requests
# 创建 Session 对象(自动管理 Cookie)
session = requests.Session()
# 登录参数
login_url = "https://example.com/login"
login_data = {
"username": "your_account",
"password": "your_password"
}
# 发送登录请求,Session 自动保存返回的 Cookie
resp = session.post(login_url, data=login_data)
print("登录状态码:", resp.status_code)
# 后续请求自动携带 Cookie
profile_url = "https://example.com/profile"
resp2 = session.get(profile_url)
print(resp2.text) # 已登录后的页面内容
对比普通 requests.get: 用 Session 后,鉴权信息自动带上,不用手动操作 Cookie。
三、实战:模拟登录 GitHub
GitHub 的登录流程比较典型,包含表单提交和 Token 校验。
python
import requests
from bs4 import BeautifulSoup
session = requests.Session()
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0"
})
def login_github(username, password):
"""模拟登录 GitHub"""
login_url = "https://github.com/login"
# 第一步:访问登录页,获取 authenticity_token
resp = session.get(login_url)
soup = BeautifulSoup(resp.text, "html.parser")
# GitHub 登录表单需要 token 防 CSRF 攻击
token = soup.find("input", {"name": "authenticity_token"}).get("value")
# 第二步:提交登录表单
data = {
"login": username,
"password": password,
"authenticity_token": token,
"commit": "Sign in"
}
session.post(login_url, data=data)
# 验证登录是否成功
profile = session.get("https://github.com/" + username)
if username in profile.text:
print("登录成功!")
return True
else:
print("登录失败")
return False
要点: 很多网站的登录流程不是一步的------先 GET 拿 Token,再 POST 提交。直接用账号密码去 POST 大概率失败。
四、处理验证码
1. 图形验证码------保存到本地手动识别
python
import requests
session = requests.Session()
# 先获取验证码图片
captcha_url = "https://example.com/captcha"
resp = session.get(captcha_url)
# 保存到本地,手动查看
with open("captcha.png", "wb") as f:
f.write(resp.content)
# 手动输入验证码
code = input("请输入验证码: ")
# 提交登录
login_data = {
"username": "your_account",
"password": "your_password",
"captcha": code
}
resp = session.post("https://example.com/login", data=login_data)
2. 使用打码平台(推荐)
对于大规模采集,手动输入不现实,可以用打码平台自动识别。
python
import requests
import base64
# 假设使用某打码平台的 API
def recognize_captcha(image_url):
"""自动识别验证码"""
# 下载验证码
img_data = session.get(image_url).content
# 调用打码平台 API
api_url = "http://api.damaplatform.com/recognize"
files = {"image": ("captcha.png", img_data)}
data = {"token": "your_api_key"}
resp = requests.post(api_url, files=files, data=data)
return resp.json().get("result") # 返回识别的文本
# 使用
code = recognize_captcha("https://example.com/captcha")
login_data = {
"username": "your_account",
"password": "your_password",
"captcha": code
}
国内常用的打码平台:超级鹰、打码兔、图鉴等,识别准确率一般在 80%-95%。
3. 保存 Cookie 到本地,下次复用
有些验证码太难识别,那就保存登录后的 Cookie 到文件,下次直接用。
python
import json
# 登录成功后,保存 Cookie
def save_cookies(session, filepath="cookies.json"):
cookies = session.cookies.get_dict()
with open(filepath, "w") as f:
json.dump(cookies, f)
print("Cookie 已保存")
# 下次登录时,加载 Cookie
def load_cookies(session, filepath="cookies.json"):
with open(filepath, "r") as f:
cookies = json.load(f)
session.cookies.update(cookies)
print("Cookie 已加载")
# 使用
# 第一次:手动登录,保存 Cookie
session = requests.Session()
# ... 执行登录流程 ...
save_cookies(session)
# 之后:直接加载 Cookie,无需登录
session2 = requests.Session()
load_cookies(session2)
resp = session2.get("https://example.com/profile")
print(resp.text)
Cookie 有效期: 有的网站 Cookie 几天过期,有的几个月。如果发现返回登录页,说明需要重新登录。
五、实战:模拟登录知乎
python
import requests
import re
import time
class ZhihuLogin:
def __init__(self):
self.session = requests.Session()
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0",
"Referer": "https://www.zhihu.com/signin"
})
def login(self, phone, password):
"""知乎手机号登录"""
login_api = "https://www.zhihu.com/api/v3/oauth/sign_in"
# 获取登录页面的 xsrf token
resp = self.session.get("https://www.zhihu.com/signin")
xsrf = re.search(r'name="xsrf" value="([^"]+)"', resp.text)
xsrf = xsrf.group(1) if xsrf else ""
# 登录参数
timestamp = int(time.time() * 1000)
data = {
"client_id": "c3cef7c66a1843f8b3a9e6a1e3160e20",
"grant_type": "password",
"source": "com.zhihu.web",
"username": phone,
"password": password,
"captcha": "", # 验证码(可为空,触发滑块时再填)
"lang": "cn",
"ref_source": "homepage",
"utm_source": "",
"timestamp": timestamp,
"signature": "" # 实际需要计算签名,简化示例
}
resp = self.session.post(login_api, json=data)
if resp.status_code == 200 and "access_token" in resp.text:
print("知乎登录成功!")
return True
else:
print("登录失败:", resp.text)
return False
def get_following(self):
"""获取关注列表(登录后)"""
url = "https://www.zhihu.com/api/v4/me/followees"
resp = self.session.get(url)
return resp.json()
# 使用
zhihu = ZhihuLogin()
if zhihu.login("your_phone", "your_password"):
following = zhihu.get_following()
print("关注人数:", len(following.get("data", [])))
注意: 知乎的登录接口有签名校验,实际开发中可能需要更复杂的方式(如用 Selenium 模拟真实浏览器登录)。
六、Selenium 模拟登录------最通用方案
遇到接口加密、签名验证等复杂情况时,用 Selenium 控制真实浏览器登录是最省心的方案。
python
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import pickle # Python 序列化工具
# 启动浏览器
driver = webdriver.Chrome()
driver.get("https://weibo.com/login")
# 等待用户手动登录(给足够时间扫码或输密码)
print("请在浏览器中手动登录...")
time.sleep(30) # 留 30 秒手动操作
# 保存 Cookie 到文件
with open("weibo_cookies.pkl", "wb") as f:
pickle.dump(driver.get_cookies(), f)
print("Cookie 已保存")
driver.quit()
下次直接用 Cookie 登录,不用再手动扫码:
python
from selenium import webdriver
import pickle
driver = webdriver.Chrome()
driver.get("https://weibo.com")
# 加载 Cookie
with open("weibo_cookies.pkl", "rb") as f:
cookies = pickle.load(f)
for cookie in cookies:
# 注意要设置正确的 domain
driver.add_cookie(cookie)
# 刷新页面,已登录状态
driver.get("https://weibo.com")
time.sleep(5)
print("登录成功后的页面:", driver.title)
Selenium 模拟登录的核心策略: 让用户手动登录一次 → 保存 Cookie → 后续自动使用。
七、常见问题与排查思路
| 问题 | 原因 | 解决 |
|---|---|---|
| 登录成功但请求报 403 | 缺少 Referer 或 User-Agent | 加上常见的请求头 |
| Cookie 频繁过期 | 网站有主动踢下线机制 | 缩短 Cookie 复用间隔 |
| 无法获取 Token | 表单字段名动态变化 | 用正则或解析器动态提取 |
| 验证码无法识别 | 图形干扰太强 | 转第三方打码平台 |
| 接口加密复杂 | 有签名算法 | 用 Selenium 替代 requests |
排查方法论:
- 浏览器 F12 → Network → 勾选 Preserve log
- 手动登录一次,看浏览器发了什么请求和数据
- 用 Python 一模一样地复现
- 如果某个参数找不到来源 → 可能是前端 JS 生成的 → 用 Selenium
八、总结
模拟登录的本质就是:用代码模拟浏览器和服务器之间的认证交互。
简单场景 → requests.Session(自动管理 Cookie)
一般场景 → 加验证码识别或 Token 提取
复杂场景 → Selenium 控制浏览器 + 保存 Cookie 复用
建议掌握的顺序:requests.Session 入门 → 加验证码处理 → 最后上 Selenium。不要一上来就用 Selenium,太重了。
💡 觉得有用的话,点赞 + 关注【张老师技术栈】吧!每周更新 Java/Python/爬虫 实战干货,不让你白来。