Java 模拟58登录(二) 实现

标签(空格分隔): Java


实习期间需要做一个模拟58登录然后爬取简历,之前已经写了一篇分析,现在具体实现过程

有关过程的分析,可以参考我的另一篇博客 Java 模拟58登录(一) 分析

实现

流程

根据之前的分析可以得出58登录的大致流程如下

  • 发送Get请求(data?), 获取 token
  • 发送Get请求(getcode?), 请求发送手机验证码, 同时获得一个tokencode
  • 发送Get请求(login?), 输入手机号,动态码以及其他相关参数来发送登录请求
  • 登录成功

预处理

除了上述所说的步骤外,还有很多需要处理的底层实现细节,比如解析Cookie, 构造必须的参数

设置必须参数

  • FINGERPRINT 和FINGERPRINT2是网页登录的时候直接抓取的,我试过随机修改后面几个数字依旧可以登录
  • JQUERYSTR 只是jquery调用时候自动生成的参数,为了不出现什么问题我也加上了
  • initTime initTime表示页面加载时间,后面加密时候需要用到的时间戳这个参数,这里所有需要的时间戳都是(需要的时间戳时刻b-initTime+ const time 1411093327735L)
  • TOKENCODE 和 TOKEN 是调用的时候获取的参数
    private String FRONTEND_URL = "http://passport.58.com/frontend/data?";private String TOKENCODE_URL = "http://passport.58.com/mobile/getcode?";private String LOGIN_URL = "https://passport.58.com/mobile/pc/login?";private String FINGERPRINT = "421A592E9D98DC7C0711A36033A582E84360ED23C621CCE3_011";private String FIGNERPRINT2 = "zh-CN|24|1|4|1600_900|1600_860|-480|1|1|1|undefined|undefined|"+ "unknown|Win64|unspecified|1|false|false|false|true|false|"+ "0_true_true|d41d8cd98f00b204e9800998ecf8427F|b01de87fcefd32c68d348cd9d18b62d9";private String JQUERYSTR = "jQuery183025066063002634587_" + getNow();private long initTime = (new Date()).getTime();private String TOKENCODE = "";private String TOKEN = "";

解析Cookie

这里实际写的时候遇到了坑点, 最初底层实现Cookie是参考stackoverflow中的那种实现
但是如果Cookie value中含有”=”,解析就是失败,刚好58的session Cookie 中含有这个!!!我也是失败很多次才知道

    protected CookieStore cookieStore = new BasicCookieStore();public void setCookieStore(HttpResponse httpResponse) {Header[] headers = httpResponse.getHeaders("Set-Cookie");if (headers != null && headers.length > 0) {for (int i = 0; i < headers.length; i++) {String setCookie = headers[i].getValue();try {BasicClientCookie cookie = this.parseRawCookie(setCookie);if (!cookie.isExpired(new Date())) {this.cookieStore.addCookie(cookie);}} catch (Exception e) {// do nothing}}}this.cookieStore.clearExpired(new Date());}//使用java.net.HttpCookie自带的解析,然后手动转换成BasicClientCookie
//这里java.net.HttpCookie会有些默认行为需要注意protected BasicClientCookie parseRawCookie(String rawCookie) throws Exception {List<HttpCookie> cookies = HttpCookie.parse(rawCookie);if (cookies.size() < 1)return null;HttpCookie httpCookie = cookies.get(0);BasicClientCookie cookie = new BasicClientCookie(httpCookie.getName(), httpCookie.getValue());if (httpCookie.getMaxAge() >= 0) {Date expiryDate = new Date(System.currentTimeMillis() + httpCookie.getMaxAge() * 1000);cookie.setExpiryDate(expiryDate);}if (httpCookie.getDomain() != null)cookie.setDomain(httpCookie.getDomain());if (httpCookie.getPath() != null)cookie.setPath(httpCookie.getPath());if (httpCookie.getComment() != null)cookie.setComment(httpCookie.getComment());cookie.setSecure(httpCookie.getSecure());return cookie;}

解析Response String

返回的Response类似于下面,需要提取其中的键值对

jQuery18305434571389149673_1515995590691({“code”:0,”data”:{“remainTime”:0,”token”:”7pjUnv6fhBONHh7A_4HrN_2rH4is-gC8”,”rsaModulus”:”xxx固定值xxx”,
“rsaExponent”:”010001”,”totalTime”:60,”mobile”:”手机号”},”msg”:”“})

    protected String getResponseParameter(String response, String parameterName) {String result = response.replaceAll(",|\"|:", " ");StringTokenizer tokenizer = new StringTokenizer(result, " ");while (tokenizer.hasMoreTokens() && !tokenizer.nextToken().equals(parameterName)) {}String token = tokenizer.nextToken();return token;}

发送Get请求模块

因为后面很多都用到get 请求,所以这里封装一下

    public String doGet(String url, String host) throws Exception {CloseableHttpClient client = this.createHttpClient();HttpGet get = new HttpGet(url);get.addHeader("Connection", "keep-alive");get.addHeader("accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");get.addHeader("accept-encoding", "gzip, deflate, br");get.addHeader("accept-language", "en-US,en;q=0.9");get.addHeader("upgrade-insecure-requests", "1");get.addHeader("user-agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36");get.addHeader("Host", host);CloseableHttpResponse response = client.execute(get);if (response == null) {throw new Exception("network error, unable to connect to 51job");}setCookieStore(response);HttpEntity entity = response.getEntity();InputStream stream = entity.getContent();String result = IOUtils.toString(stream, "utf-8");IOUtils.closeQuietly(stream);EntityUtils.consumeQuietly(entity);HttpClientUtils.closeQuietly(client);return result;}

加密字符串

QuanzhouJSUtil是一个调用js的类

    protected String encryptStr(String str) {Long timeSpan = 1411093327735L;Long randomLong = timeSpan + (new Date()).getTime() - initTime;String timeSign = String.valueOf(randomLong);String passwd = timeSign + str;String encryptPwd = QuanzhouJSUtil.getEncryptString(passwd);return encryptPwd;}

发送动态码

    public void getPhoneCode(String phoneNumber) throws Exception {// 获得token,然后用token作为参数获取tokenCode, 然后发送验证码登录时候需要用到tokenCode和tokenString result = doGet(FRONTEND_URL + getJQueryCallBackStr(), "passport.58.com");TOKEN = getResponseParameter(result, "token");// 获取token codeString enPhone = encryptStr(phoneNumber);String tokenCodeURL = TOKENCODE_URL + "mobile=" + enPhone + "&validcode=&source=pc-login&vcodekey=&token="+ TOKEN + "&voicetype=0&codetype=0&fingerprint=" + FINGERPRINT + "&" + getJQueryCallBackStr() + "&path="+ "http://my.58.com";result = doGet(tokenCodeURL, "passport.58.com");TOKENCODE = getResponseParameter(result, "tokencode");}

发送动态码

    public void getPhoneCode(String phoneNumber) throws Exception {// 获得token,然后用token作为参数获取tokenCode, 然后发送验证码登录时候需要用到tokenCode和tokenString result = doGet(FRONTEND_URL + getJQueryCallBackStr(), "passport.58.com");TOKEN = getResponseParameter(result, "token");// 获取token codeString enPhone = encryptStr(phoneNumber);String tokenCodeURL = TOKENCODE_URL + "mobile=" + enPhone + "&validcode=&source=pc-login&vcodekey=&token="+ TOKEN + "&voicetype=0&codetype=0&fingerprint=" + FINGERPRINT + "&" + getJQueryCallBackStr() + "&path="+ "http://my.58.com";result = doGet(tokenCodeURL, "passport.58.com");TOKENCODE = getResponseParameter(result, "tokencode");}

测试登录

    @Testpublic void testLogin58(){preLogin();String phoneNum = "";String mobileCode = "";System.out.println("请输入你的手机号码:");Scanner scanner = new Scanner(System.in);phoneNum = scanner.nextLine();try {getPhoneCode(phoneNum);System.out.println("请输入你的手机验证码:");mobileCode = scanner.nextLine();loginJob58(phoneNum, mobileCode);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}//add some code to doscanner.close();}

Java 模拟58登录(二) 实现相关推荐

  1. Java 模拟58登录

    Java 模拟 58登录 (一) 分析 标签(空格分隔): Java 实习期间需要做一个模拟58登录然后爬取简历,第一次做项目遇到很多坑 同时网上关于58登录的又没有很多资料,遇到了很多坑,这里记录一 ...

  2. java 模拟登录58同城_Java 模拟58登录(二) 实现

    实现 流程 根据之前的分析可以得出58登录的大致流程如下发送Get请求(data?), 获取 token 发送Get请求(getcode?), 请求发送手机验证码, 同时获得一个tokencode 发 ...

  3. java模拟微博登录_Python模拟微博登陆,亲测有效

    今天想做一个微博爬个人页面的工具,满足一些不可告人的秘密.那么首先就要做那件必做之事!模拟登陆-- 我对代码进行了优化,重构成了Python 3.6 版本,并且加入了大量注释方便大家学习. PC 登录 ...

  4. java 模拟get登录_java 模拟get请求

    原码 /** * GET页面的内容 * * @param cityMsg * @return 返回HTML源代码 */ private  String getHtmlCode(String url,S ...

  5. appium java模拟微信登录,python实战之结合Appium自动化操作微信

    本教程操作环境:win7系统,JDK1.8,Appium,Python3.7,android-sdk,JDK,模拟器 1.Appium介绍 Appium是一个开源的自动化测试工具,其支持iOS和安卓平 ...

  6. java模拟网银登录_用java编写模拟网上银行登录及存取款业务

    展开全部 public class Account { protected String accId; protected String name; protected double money; p ...

  7. 微信群控系统制作系列一——java模拟登录网页版微信

    PS:很多人咨询我怎么做手机群控系统,因此我开了个制作群控系统的系列,准备分五期讲解群控系统的制作.前两篇是基础内容. 今天做个简单的java模拟登录网页版微信. 既然要做模拟登录,那么我们一定要了解 ...

  8. CSDN实训 - Java模拟二次验证码(动态令牌)

    文章目录 前言 一.什么是动态令牌? 二.使用的Jar包 1. 生成二维码Jar包 2. Apache Commons Codec 3. 项目工具类 4. 下载链接 三.IDEA导入外部Jar包 四. ...

  9. 用java模拟登录正方教务系统,抓取课表和个人成绩等数据

    之前学了一些java web的编程,理解了web应用的原理后,就突然想到,可以用java模拟登录吉珠的教务系统,然后爬取里面的课表.成绩.个人信息等等数据,然后就可以写成一个简易的课表APP. 一.第 ...

最新文章

  1. 运行hadoop自带的wordcount例子
  2. vue 下echarts卸载和安装指定版本
  3. Codeforces 997D Cycles in Product (点分治、DP计数)
  4. SpriteBuilder中不能编辑自定义类或不能给节点添加属性的解决
  5. C语言的整型溢出问题
  6. 【Python】Matplotlib绘制蓝天下的普通房屋
  7. python word 英语音标_(完整word版)英语音标大全,推荐文档
  8. HDU4712 Hamming Distance (随机化)
  9. ZXing开发彩色二维码
  10. 【2015 NEERC - G 】Garden Gathering【距离计算变形、数学巧妙转换】
  11. android视频播放器ui,Android史上最强视频音频播放器 精美UI Fragment实现
  12. w7为什么计算机没有摄像头.,W7笔记本摄像头怎么打开
  13. 不服?来战!2017 CCF BDCI百万元巨奖各有所属
  14. 创新工场王嘉平开讲:low-level的计算机视觉
  15. 手动开启/关闭macOS HiDPI,让2k显示器完美适配macOS,解决紫屏问题
  16. java加载顺序_类加载过程中几个重点执行顺序整理
  17. 教新手了解怎么从网络中赚钱
  18. 阿里云服务器安装mysql
  19. 《因果学习周刊》第13期:ICLR 23因果推断高分论文
  20. Qt编写的项目作品7-视频监控系统

热门文章

  1. one平台 复现代码 节点缓存感知的DTN概率路由算法
  2. Python 写商品清单(加入购物车)
  3. 面向对象02 - 案例:王者荣耀英雄选择
  4. PyG OGB 使用过程记录
  5. 五子棋算法--禁手的判断
  6. 央美“毕业”开画展,少女画家小冰开放绘画能力为亿万人作画
  7. Intel 软件开发技术概要与在开发中的运用(讲解并行计算,多核心优化,以及Intel开发工具)
  8. 腾讯太极广告一站式机器学习平台的产品化之路
  9. 2021年中国核受体γ市场趋势报告、技术动态创新及2027年市场预测
  10. axios-雷磊呕心沥血之作不喜勿喷