【实战解析】Python Session 与 Cookie 模拟登录:以 17k 小说网为例

📅 2026/7/15 2:30:27
【实战解析】Python Session 与 Cookie 模拟登录:以 17k 小说网为例
1. 理解Session与Cookie的登录机制当你第一次访问17k小说网时服务器会给你分配一个身份证——这就是Cookie。它像音乐会门票一样记录着你的登录状态。但普通请求就像单次门票每次都要重新验票。而Session对象则是VIP通行证自动帮你保管好这张门票。我刚开始做爬虫时经常遇到这样的问题明明登录成功了却抓不到书架数据。后来发现是Cookie没带对就像去银行取钱却忘了带银行卡。requests.Session()就是解决这个痛点的利器它会自动管理Cookie的生命周期。用生活场景来比喻普通请求就像每次去咖啡店都要重新报会员号而Session则是店员认出你的脸自动关联账户。在17k小说网的案例中登录接口返回的Set-Cookie头部就是服务器给我们的会员凭证。2. 实战环境准备先确保你的Python环境有requests库没有的话用这条命令安装pip install requests我推荐使用PyCharm或VS Code这些IDE它们能直观展示JSON响应数据。曾经我在命令行调试时对着密密麻麻的JSON数据差点看花眼。调试工具就像X光机能看清HTTP请求的骨骼结构。建议先准备好测试账号千万别用主账号我有次测试时连续触发验证码导致主账号被临时冻结。可以在17k注册个专用测试号用简单的密码比如Test1234当然正式环境要用强密码。3. 分析17k登录流程打开Chrome开发者工具F12在登录时观察Network标签页。你会发现关键登录请求发送到https://passport.17k.com/ck/user/login用我的经验来看17k的登录表单相对简单主要需要{ loginName: 你的账号, password: 明文密码, # 注意有些网站会加密 remember: true # 保持登录状态 }有个坑要注意17k的密码是明文传输的这在现代网站中很少见了。我测试过几个账号发现如果密码包含特殊字符可能会出问题建议先用纯字母数字组合测试。登录成功的响应通常会包含Set-Cookie头部用户ID等基本信息有时会返回token4. 使用Session对象实现登录核心代码结构是这样的import requests session requests.Session() # 创建会话对象 login_data { loginName: test_user, password: Test1234 } login_url https://passport.17k.com/ck/user/login response session.post(login_url, datalogin_data) print(response.json()) # 查看登录结果这里有个实用技巧我习惯在开发时先打印整个响应像这样import pprint pprint.pprint(response.json())曾经我遇到过返回结果看似成功但实际登录失败的情况。后来发现是响应里有个success字段为false。所以一定要完整检查响应内容登录成功后这个session对象就自动保存了Cookie。你可以通过session.cookies查看当前携带的所有Cookie就像这样for cookie in session.cookies: print(f{cookie.name}: {cookie.value})5. 访问需要登录的页面登录后我们就能用同一个session访问个人书架了。17k的书架API地址是https://user.17k.com/ck/author/shelf?page1appKey2406394919代码非常简单shelf_url https://user.17k.com/ck/author/shelf?page1appKey2406394919 shelf_response session.get(shelf_url) print(shelf_response.json())这里有个实际项目中的经验我建议先检查响应状态码。有时即使带了Cookie也可能返回403或401if shelf_response.status_code 200: data shelf_response.json() # 处理数据... else: print(f请求失败状态码{shelf_response.status_code})6. 处理常见问题与异常6.1 验证码问题连续登录失败几次后17k可能会要求验证码。我建议控制登录频率每次测试后手动注销可以尝试识别简单验证码但要注意法律风险最稳妥的方法是人工处理验证码后保存Cookie6.2 Cookie过期Session保存的Cookie默认会过期。在我的测试中17k的登录状态大约保持1天。解决方案# 持久化Cookie import pickle # 保存 with open(17k_cookie.pkl, wb) as f: pickle.dump(session.cookies, f) # 加载 with open(17k_cookie.pkl, rb) as f: session.cookies.update(pickle.load(f))6.3 请求频率限制抓取数据时要控制节奏我常用time.sleepimport time import random time.sleep(random.uniform(1, 3)) # 随机等待1-3秒7. 完整代码示例结合上述所有要点这是完整的可运行代码import requests import time import pprint def login_17k(username, password): session requests.Session() # 配置请求头更模拟浏览器 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36, Origin: https://passport.17k.com, Referer: https://passport.17k.com/login/ } login_url https://passport.17k.com/ck/user/login login_data { loginName: username, password: password } print(正在登录...) login_response session.post(login_url, datalogin_data, headersheaders) result login_response.json() if result.get(status) 1: print(登录成功) return session else: print(登录失败:, result.get(message)) return None def get_book_shelf(session): shelf_url https://user.17k.com/ck/author/shelf?page1appKey2406394919 print(\n获取书架数据...) response session.get(shelf_url) if response.status_code 200: return response.json() else: print(f请求失败状态码{response.status_code}) return None if __name__ __main__: # 替换为你的测试账号 USERNAME your_test_account PASSWORD your_password session login_17k(USERNAME, PASSWORD) if session: time.sleep(1) # 礼貌等待 shelf_data get_book_shelf(session) if shelf_data: print(\n书架数据) pprint.pprint(shelf_data)8. 扩展应用场景掌握了这个技术后你还能做很多有趣的事情8.1 自动签到很多小说网站有签到功能用Session可以轻松实现def daily_checkin(session): checkin_url https://user.17k.com/ck/signin response session.post(checkin_url) return response.json()8.2 数据监控定时检查小说更新情况def check_updates(session, book_id): update_url fhttps://user.17k.com/ck/book/{book_id}/updates response session.get(update_url) return response.json()8.3 多账号管理用字典管理多个Sessionaccounts { account1: {username: user1, password: pass1, session: None}, account2: {username: user2, password: pass2, session: None} } for acc in accounts.values(): acc[session] login_17k(acc[username], acc[password])在实际项目中我建议把这类操作封装成类比如class NovelSpider: def __init__(self, username, password): self.session requests.Session() self.login(username, password) def login(self, username, password): # 登录实现... pass def get_shelf(self): # 获取书架... pass # 其他方法...最后提醒一点爬虫要遵守网站的robots.txt规则控制请求频率不要给服务器造成负担。我曾经因为太热情请求太快被临时封过IP这个教训分享给大家。