尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

人人网自动登录脚本实战:JS逆向与Playwright方案

发布时间:2026/9/29 19:02:05

资讯中心
01
ARTICLE

人人网自动登录脚本实战:JS逆向与Playwright方案

人人网自动登录脚本实战:JS逆向与Playwright方案
简介这份资源是一套面向 Java 开发者的简易版人人网校内自动登录程序针对网上流传的老版校内登录代码无法直接使用的问题由作者自行编写实现。适合具备一定 Java 基础、希望研究 HTTP 模拟登录流程或进行二次开发的读者参考。压缩包共 4 个文件以 3 个 zip 依赖库和 1 个 java 源码为主整体约 4.31MB其中源码文件承载核心登录逻辑zip 包则提供 commons-httpclient、commons-codec、commons-logging 等运行所需类库需自行添加至工程。目前已有 42837 人学习下载热度较高。作者定位为简易版未附加多余功能重在抛砖引玉读者可借此理解登录请求构造、参数编码与 Cookie 处理等关键环节并在此基础上扩展签到、抓取等个性化功能也便于与作者交流讨论、互相学习。1. 人人网自动登录从手动签到到脚本托管的真实需求人人网校内自动登录这件事表面看只是省去每天输账号密码的几秒钟实际背后是一类很典型的自动化诉求老站点、老账号、老接口但登录链路里塞满了动态参数和前端加密用常规的 requests 直接 POST 往往连第一关都过不去。我最早接触这个需求是帮一个做校友数据整理的朋友处理他手里几个沉寂多年的校内账号需要每天定时拉取站内消息和好友动态手动登录既费时又容易触发风控。后来发现网上搜“人人网自动登录”的人诉求基本集中在三类一是账号长期不用怕被回收想靠定时登录保活二是做历史数据归档需要稳定拿到登录态三是纯粹想练手 JS 逆向和自动化拿老站点当靶场。无论哪一种核心都绕不开同一个问题——怎么在脚本里复现浏览器那套登录流程并且让它在无人值守的情况下持续跑下去。这一篇就按我实际踩过的路把人人网自动登录从抓包分析到脚本落地再到长期维护的完整链条拆开讲能直接抄的代码和参数都会给到踩过的坑也会标清楚。2. 拆解人人网登录链路从抓包到定位加密参数2.1 用浏览器开发者工具抓一次完整登录请求动手写代码之前先得把登录时浏览器到底发了什么搞清楚。打开人人网登录页按 F12 切到 Network 面板勾选 Preserve log然后正常输入账号密码点登录。这时候会看到一串请求重点盯两类一个是返回登录页 HTML 的文档请求另一个是真正提交凭证的 XHR 或表单请求。人人网的老架构里登录提交通常走https://www.renren.com/PLogin.do这个端点方法可能是 POSTContent-Type 多为application/x-www-form-urlencoded。在请求详情里把 Payload 和 Response Headers 都展开你会看到除了email和password之外还有几个看起来像乱码的字段比如icode、key、captcha之类。这些就是后面脚本里必须动态生成的拦路虎。抓包时注意把password字段的值复制出来它大概率不是你的明文密码而是一段固定长度的十六进制或 base64 字符串这说明前端做了加密。同时看一眼 Response Headers 里有没有Set-Cookie登录成功后服务端会下发会话 cookie后续所有请求都得带上它。2.2 定位密码加密逻辑与动态参数来源抓包只能看到密文要复现就得找到加密函数。在 Sources 面板里按 CtrlShiftF 全局搜索password这个关键词或者直接搜PLogin.do很快能定位到提交登录的那个 JS 文件。人人网早年用的是自己封装的一套加密常见的是对密码做一次 MD5 再拼接时间戳或随机数也有版本是对密码明文做 RSA 公钥加密。我遇到过的版本里密码字段是先经过一个叫encrypt的函数处理内部调用了hex_md5之类的实现。找到函数后不要急着用 Python 重写先把整个 JS 文件下载下来用 Node.js 在本地跑一遍确认输入输出对得上。动态参数方面icode通常是登录页 HTML 里内嵌的一个隐藏 input 值用正则从页面源码里抠出来即可key可能是服务端下发的一次性 token同样藏在页面里。这一步的关键是分清哪些参数是页面里现成的哪些是需要本地计算的前者用正则提取后者用 JS 引擎执行。2.3 用 Python 复现登录请求的最小闭环定位清楚之后先用 Python 搭一个最小可跑的登录脚本把整个链路串起来。下面这段代码演示了从获取登录页、提取动态参数、计算加密密码到提交登录的完整流程依赖requests和PyExecJS用来跑那段加密 JS。import re import requests import execjs # 1. 创建会话保持 cookie session requests.Session() session.headers.update({ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Referer: https://www.renren.com/, }) # 2. 获取登录页提取 icode 和 key login_page session.get(https://www.renren.com/) icode re.search(rnameicode\svalue([^]), login_page.text) key re.search(rnamekey\svalue([^]), login_page.text) icode icode.group(1) if icode else key key.group(1) if key else # 3. 加载本地保存的加密 JS计算密文密码 with open(encrypt.js, r, encodingutf-8) as f: js_code f.read() ctx execjs.compile(js_code) encrypted_pwd ctx.call(encrypt, your_password) # 4. 构造登录表单并提交 payload { email: your_account, password: encrypted_pwd, icode: icode, key: key, origURL: https://www.renren.com/, domain: renren.com, } resp session.post(https://www.renren.com/PLogin.do, datapayload, allow_redirectsTrue) # 5. 验证登录态检查响应里是否包含用户昵称或跳转后的首页特征 if 用户中心 in resp.text or resp.url ! https://www.renren.com/: print(登录成功当前 cookie:, session.cookies.get_dict()) else: print(登录失败检查参数或风控)这段代码的逻辑很直白先拿页面里的动态值再用 JS 引擎算出密文最后带着完整参数提交。参数说明上icode和key必须每次登录前重新获取不能写死encrypted_pwd依赖的encrypt.js就是从 Sources 里扒下来的那个文件保存到本地时注意把里面依赖的其他函数一并带上否则execjs会报未定义。allow_redirectsTrue是为了让 requests 自动跟随登录后的 302 跳转方便后续判断。如果返回的页面里出现了只有登录后才能看到的内容比如好友列表或站内信入口就说明会话已经建立。这一步跑通之后自动登录的骨架就算立住了剩下的就是保活和异常处理。3. 把登录脚本跑成定时任务调度、保活与状态检查3.1 用 schedule 或 cron 驱动每日自动登录脚本能手动跑通之后下一步就是让它自己动起来。最轻量的做法是在 Python 里用schedule库适合脚本常驻内存的场景如果服务器上已经有 cron直接写 crontab 更省资源。下面两种方式我都用过按你的部署环境选。import schedule import time from login import do_login # 假设登录逻辑封装在 do_login 函数里 # 每天上午 9 点和晚上 9 点各登录一次降低账号被判定为休眠的概率 schedule.every().day.at(09:00).do(do_login) schedule.every().day.at(21:00).do(do_login) while True: schedule.run_pending() time.sleep(60)如果走 cron直接在 crontab 里写一行# 每天 9 点执行一次登录脚本日志追加到 login.log 0 9 * * * /usr/bin/python3 /path/to/login.py /path/to/login.log 21schedule的优点是可以在同一个进程里做更多事比如登录后顺便拉取数据cron 的优点是简单可靠脚本跑完就退出不占内存。参数上登录频率别设太高一天两次足够保活设成每分钟一次反而容易触发风控。日志一定要留追加写入方便回头查是哪天开始失败的。3.2 登录态失效的检测与自动重登定时登录不等于登录态一直有效。人人网的会话 cookie 有有效期可能几小时也可能几天取决于服务端策略。所以脚本不能只管登录还得在每次执行业务操作前检查当前会话是否还有效。我的做法是封装一个ensure_login函数先拿一个需要登录才能访问的轻量接口探活比如站内消息数接口如果返回的是登录页或者 302 到登录页就重新走一遍登录流程。def ensure_login(session): # 探活接口访问一个需要登录的页面检查是否被重定向 check session.get(https://www.renren.com/notify/list, allow_redirectsFalse) if check.status_code 302 and login in check.headers.get(Location, ): print(登录态失效重新登录) return do_login(session) return session这里的关键是allow_redirectsFalse不让 requests 自动跳转这样才能从 302 的 Location 头里判断出是否被踢回登录页。探活接口别选太重选个返回体小的页面减少流量和风控暴露面。重登之后记得把新的 cookie 更新到 session 里后续请求自然就带上了。3.3 用 cookie 持久化减少重复登录次数如果业务需要频繁请求每次都重新登录既慢又危险。更稳的做法是把登录成功后的 cookie 存到本地文件下次启动先加载 cookie 试跑失效了再重新登录。这样大部分时间都在复用会话只有过期时才走一次完整登录。import pickle import os COOKIE_FILE renren_cookies.pkl def save_cookies(session): with open(COOKIE_FILE, wb) as f: pickle.dump(session.cookies, f) def load_cookies(session): if os.path.exists(COOKIE_FILE): with open(COOKIE_FILE, rb) as f: session.cookies.update(pickle.load(f)) return True return Falsepickle直接序列化RequestsCookieJar对象比手动拼字符串省事。加载后先调一次ensure_login探活有效就继续用无效就删掉文件重新登录。注意 cookie 文件里包含敏感信息别提交到公开仓库本地权限设成 600。这套组合拳下来脚本基本能做到无人值守跑上几周不用管。4. 避坑与排查自动登录人人网时最容易翻车的五个点4.1 现象脚本返回 200 但页面还是登录页原因登录请求虽然发出去了但服务端没认常见于icode或key提取失败或者密码加密结果不对。人人网对这几个参数校验很严错一个就静默失败不报错只返回登录页。解决在提交前把 payload 打印出来和浏览器抓到的请求逐字段对比重点看icode是否为空、password长度是否一致。另外确认encrypt.js里的函数名和调用方式跟页面里完全一致有些版本加密函数依赖全局变量execjs环境里需要手动补上。4.2 现象登录成功但后续请求全部 302 回登录页原因cookie 没带上或者带上了但域不对。人人网的会话 cookie 可能绑定在.renren.com域下如果你手动构造请求时用了www.renren.com之外的子域cookie 不会自动携带。解决统一用session对象发请求让 requests 自己管理 cookie 域。如果是从文件加载的 cookie检查pickle反序列化后domain字段是否正确。另外注意session.headers里的Referer别乱改有些接口会校验来源。4.3 现象跑几天后突然开始返回验证码页面原因登录频率过高或 IP 变动频繁触发了风控。人人网对老账号的异常登录比较敏感尤其是短时间内多次从不同 IP 登录。解决降低登录频率到一天一两次固定出口 IP别用动态代理池。如果已经出了验证码先停脚本几天手动登录一次养一养账号再恢复时把间隔拉长。验证码本身不建议硬破成本高且容易把账号搞封。4.4 现象execjs 报 “ReferenceError: hex_md5 is not defined”原因从浏览器扒下来的 JS 文件不完整加密函数依赖的其他工具函数没一起保存。人人网的 JS 经过打包函数之间可能有隐式依赖。解决在 Sources 里找到加密函数后顺着调用链把依赖的函数都复制到一个文件里或者直接用jsdom在 Node 里跑整个页面上下文。更省事的办法是用 Playwright 直接操控浏览器登录拿到 cookie 后再交给 requests 用绕过 JS 逆向。4.5 现象定时任务在服务器上跑本地正常服务器失败原因服务器环境缺少依赖或者 Python 版本不一致导致execjs找不到 JS 运行时。execjs需要系统里有 Node.js 或 PyV8 之类的运行时本地开发机往往已经装了 Node服务器上可能是干净的。解决在服务器上装 Node.js或者改用PyExecJS并显式指定运行时。另外检查服务器时间是否同步有些加密逻辑依赖时间戳时间偏差太大会导致密文对不上。5. 进阶用 Playwright 接管登录把逆向成本降到零前面那套 JS 逆向加 requests 的方案胜在轻量、跑得快但维护成本不低——人人网前端一改版加密逻辑或参数名一变脚本就得跟着修。如果你不想反复跟 JS 较劲或者登录链路里掺了更复杂的风控比如行为验证更省心的路子是用 Playwright 直接驱动一个真实浏览器完成登录然后把登录后的 cookie 导出来给 requests 复用。这样登录环节完全交给浏览器你只需要维护“打开页面、填表单、点登录、等跳转”这几步前端怎么加密都跟你无关。下面是一个可复用的 Playwright 登录函数跑完之后把 cookie 转成 requests 能用的格式。from playwright.sync_api import sync_playwright import requests def login_with_playwright(account, password): with sync_playwright() as p: browser p.chromium.launch(headlessTrue) context browser.new_context() page context.new_page() page.goto(https://www.renren.com/) # 等待登录表单出现填入账号密码 page.fill(input[nameemail], account) page.fill(input[namepassword], password) page.click(input[typesubmit]) # 等待跳转完成判断是否进入首页 page.wait_for_url(**/home**, timeout15000) cookies context.cookies() browser.close() # 把 Playwright 的 cookie 转成 requests 的 cookie jar session requests.Session() for c in cookies: session.cookies.set(c[name], c[value], domainc[domain]) return session这段代码的核心是context.cookies()它返回的是浏览器当前所有 cookie 的列表包含 name、value、domain 等字段。转成 requests 的 session 后后续所有请求都可以用这个 session 发服务端看来就是同一个浏览器在操作。参数上headlessTrue适合服务器环境本地调试时可以设成 False 方便看页面wait_for_url的超时时间给足老站点加载慢15 秒比较稳妥。如果登录后需要处理验证码可以在page.click之后加一段等待人工介入的逻辑或者接入打码平台但那就另说了。这套方案的成本在于需要装 Playwright 和对应的浏览器内核服务器上多占几百 MB 磁盘跑起来也比纯 requests 慢几秒。但换来的是极高的稳定性——只要页面结构不大改登录逻辑几乎不用动。我的习惯是如果只是短期跑个数据归档用 requests 方案快速搞定如果要长期保活、频繁登录直接上 Playwright省下来的调试时间远比那点资源值钱。另外提醒一句不管用哪种方案账号密码都别硬编码在脚本里用环境变量或单独的配置文件读取避免泄露。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。