使用OkHttp模拟登陆LeetCode
前言
网上有很多模拟登陆 LeetCode 的教程,但是基本都是使用 Python 来实现的。作为一个 Java 语言爱好者,因此想用 Java 来实现下。在实现的过程中,也遇到了一些坑点,故在此作为记录。
过程
根据浏览器F12分析登陆页面

从上图可以看出,LeetCode 生成一个 token ,然后在登陆的时候带上这个信息,因此我们模拟登陆的大致思路:首先获取得到 cookie(包含有token),然后在登陆的时候带上这个 cookie 信息,完成 LeetCode 的验证机制,进行模拟登陆。
但是直接进行模拟带上 login(用户名)、password(密码)、csrfmiddlewaretoken(验证信息)是失败的,提示 Forbidden。思考无果,另开思路。
用 fiddler 进行抓包,未登陆状态,数据如下图(也可用浏览器F12来进行分析):

登陆状态,数据如下图,从图中,我们可以发现,其 Content-Type 字段与我们之前常见的值不一样,其是 multipart/form-data 格式,因此我们在模拟登陆,要将其考虑进来。

创建一个 multipart/form-data 的媒体格式,然后生成我们要的请求体,至于我们要的是哪种请求体,其格式可以从 fiddler 抓包的结果获悉。
在SyntaxView中具体的详情如下:

值得注意的是 Content-Type 中的boundary只有四个“-”,而在请求体中有六个“-”,之前因为忽略了这个,一直被拒绝访问(挺坑爹的
public static final String boundary = "----WebKitFormBoundaryhG2vKxp7y2GAwhPX";
public static final MediaType MULTIPART = MediaType.parse("multipart/form-data; boundary=" + boundary);
String form_data = "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"csrfmiddlewaretoken\"" + "\r\n\r\n"
+ csrftoken + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"login\"" + "\r\n\r\n"
+ usrname + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"password\"" + "\r\n\r\n"
+ passwd + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"next\"" + "\r\n\r\n"
+ "/problems" + "\r\n"
+ "--" + boundary + "--";
RequestBody requestBody = RequestBody.create(MULTIPART,form_data);
结果
将其返回的报文打印出来,得到如下信息则表示模拟登陆成功

从 fiddler 的抓包结果中也可以证实这点

代码
package LeetCodeLogin;
import okhttp3.*;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import java.io.IOException;
import java.util.*;
import static java.lang.System.out;
public class Login {
public static final String boundary = "----WebKitFormBoundaryhG2vKxp7y2GAwhPX";
public static final MediaType MULTIPART = MediaType.parse("multipart/form-data; boundary=" + boundary);
public static void main(String... args) throws IOException {
Scanner scanner = new Scanner(System.in);
String url = "https://leetcode.com/accounts/login/";
String usrname = "xxx";
String passwd = "xxx";
Connection.Response response1 = Jsoup.connect(url)
.method(Connection.Method.GET)
.execute();
String csrftoken = response1.cookie("csrftoken");
String __cfduid = response1.cookie("__cfduid");
out.println("csrftoken = " + csrftoken);
out.println("__cfduid = " + __cfduid );
OkHttpClient client = new OkHttpClient().newBuilder()
.followRedirects(false)
.followSslRedirects(false)
.build();
String form_data = "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"csrfmiddlewaretoken\"" + "\r\n\r\n"
+ csrftoken + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"login\"" + "\r\n\r\n"
+ usrname + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"password\"" + "\r\n\r\n"
+ passwd + "\r\n"
+ "--" + boundary + "\r\n"
+ "Content-Disposition: form-data; name=\"next\"" + "\r\n\r\n"
+ "/problems" + "\r\n"
+ "--" + boundary + "--";
RequestBody requestBody = RequestBody.create(MULTIPART,form_data);
Request request = new Request.Builder()
.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary)
.addHeader("Connection","keep-alive")
.addHeader("Accept","*/*")
.addHeader("Origin","https://leetcode.com")
.addHeader("Referer",url)
.addHeader("Cookie","__cfduid=" + __cfduid + ";" + "csrftoken=" + csrftoken)
.post(requestBody)
.url(url)
.build();
Response response = client.newCall(request).execute();
out.println(response.message());
out.println(response.headers());
out.println(response.body().string());
}
}
需要注意的是,在上述代码中,我们通过下述代码禁止了重定向,来自己处理重定向请求,可参考使用OkHttp进行重定向拦截处理,若是没有进行重定向拦截,也会使得模拟登陆失败。
.followRedirects(false)
.followSslRedirects(false)
写在最后
本次模拟登陆,虽然代码很简单,但是确实也经历了一些波折,比对过 Python 和 Js 写的模拟登陆的代码,用 Java 来进行模拟似乎多了一些琐碎的细节,对于具体的为何 Python 和 Js 能如此简介的处理的原理还在琢磨中。此次,也得到了朋友 faberry 的帮助,在一些地方给了意见。
使用OkHttp模拟登陆LeetCode的更多相关文章
- 使用OKHttp模拟登陆知乎,兼谈OKHttp中Cookie的使用!
本文主要是想和大家探讨技术,让大家学会Cookie的使用,切勿做违法之事! 很多Android初学者在刚开始学习的时候,或多或少都想自己搞个应用出来,把自己学的十八般武艺全都用在这个APP上,其实这个 ...
- Python 爬虫模拟登陆知乎
在之前写过一篇使用python爬虫爬取电影天堂资源的博客,重点是如何解析页面和提高爬虫的效率.由于电影天堂上的资源获取权限是所有人都一样的,所以不需要进行登录验证操作,写完那篇文章后又花了些时间研究了 ...
- Python模拟登陆新浪微博
上篇介绍了新浪微博的登陆过程,这节使用Python编写一个模拟登陆的程序.讲解与程序如下: 1.主函数(WeiboMain.py): import urllib2 import cookielib i ...
- PHP 之 CURL 模拟登陆并获取数据
1.CURL模拟登陆的流程和步骤 2.tempnam 创建一个临时文件 3.使用CURL模拟登陆到PHP100论坛 <?php $cookie_file = tempnam('./temp',' ...
- NetworkComms V3 模拟登陆
演示NetworkComms V3的用法 例子很简单 界面如下: 服务器端代码: 开始监听: //服务器开始监听客户端的请求 Connection.StartListening(ConnectionT ...
- pytho简单爬虫_模拟登陆西电流量查询_实现一键查询自己的校园网流量
闲来无事,由于校园内网络是限流量的,查询流量很是频繁,于是萌生了写一个本地脚本进行一键查询自己的剩余流量. 整个部分可以分为三个过程进行: 对登陆时http协议进行分析 利用python进行相关的模拟 ...
- python模拟登陆知乎并爬取数据
一些废话 看了一眼上一篇日志的时间 已然是5个月前的事情了 不禁感叹光阴荏苒其实就是我懒 几周前心血来潮想到用爬虫爬些东西 于是先后先重写了以前写过的求绩点代码 爬了草榴贴图,妹子图网,后来想爬婚恋网 ...
- php模拟登陆的两种实现方法分析
php模拟登陆的实现方法分析 本文实例分析了php模拟登陆的实现方法.分享给大家供大家参考.具体分析如下: php模拟登陆的实现方法,这里分别列举两种方法实现模拟登陆人人网.具体实例代码如下: 1)使 ...
- python 模拟登陆,请求包含cookie信息
需求: 1.通过GET方法,访问URL地址一,传入cookie参数 2.根据地址一返回的uuid,通过POST方法,传入cooki参数 实现思路: 1.理解http的GET和POST差别 (网上有很多 ...
随机推荐
- 16.Linux-CentOS系统进入单用户模式修改root用户密码操作
问题描述: root用户密码忘记,进入单用户重置root用户密码 解决步骤: 1.重启服务器,在系统显示内核版本界面后“按E键”,进入内核启动项2.找到Linux16这一行段,将“ro”修改成“rw” ...
- CentOS上安装Git及配置远程仓库
首先登陆CentOS服务器,连接上服务器之后我们使用yum remove git 命令删除已安装的Git,若之前没安装过Git则不需要这一步.注意前提是你的CentOS服务器上安装了yum,这是Cen ...
- 035-OpenStack 关闭安全组
OpenStack Neutron的安全组默认会对每个网口开启MAC/IP过滤功能(防arp欺骗),不是该网口的MAC/IP发出的包会被宿主机丢弃.这种限制会导致vNF的上行网口转发的数据包被丢弃,无 ...
- wpf socket 简单通讯示例
源码下载地址:https://github.com/lizhiqiang0204/WPF-Socket 效果如下:
- spring security基本知识(三) 过滤详细说明
在我们前面的文章Spring Security 初识(一)中,我们看到了一个最简单的 Spring Security 配置,会要求所有的请求都要经过认证.但是,这并不是我们想要的,我们通常想自定义应用 ...
- git详细使用教程
一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以 ...
- 文本检错——中文拼写检查工具FASPell
最近因为相关项目需要考虑中文文本检错,然后就发现了爱奇艺发布的号称SOTA的FASPell已经开源代码,所以开始着手实现. 检错思想两步:一,掩码语言模型(MLM)产生候选字符:二,CSD过滤候选字符 ...
- OmniGraffle 7使用的探索
进去后可以将界面简化为4个主要区域:工具栏.工具栏.检查器和画布. 1.画布是在项目中创建.编辑和移动对象的地方 2.删除画布 选择编辑 画布删除画布 3.OmniGraffle项目至少需要一个画布 ...
- React Native 之TouchableOpacity组件
使用TouchableOpacity组件 实现单击事件只需要声明onPress属性即可,其他同理,实现onPressIn,onPressOut,onLongPress constructor(prop ...
- IDEA插件之自动查找bug工具
打开idea 插件搜索界面 输入 FindBugs-IDEA,安装完成后重启,选中要查找的包,右键找到对应的 FindBugs就可以开始进行自动扫描了