热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【java爬虫】HttpClient4.5模拟登录知乎

0.关于HttpClient虽然在JDK的javanet包中已经提供了访问HTTP协议的基本功能,但是对于大部分应用程序来说,JDK库本身提供的功能还不够丰富和灵活。HttpC

0.关于HttpClient

虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

  1. 实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
  2. 支持自动重定向
  3. 支持 HTTPS 协议
  4. 支持代理服务器等

1.HttpClient4.5模拟登录网站步骤

  • 创建CloseHttpClient和HttpClientContext对象
  • 创建HttpPost(类似http中的post请求)对象
  • 添加请求参数到HttpPost对象中
  • 执行请求
  • 登录成功

由于网站模拟登录都会有验证码,关于验证码的处理一般有以下两种方式:

  1. 验证码识别接口(大多都是收费的),这种情况适合大规模登录。
  2. 将验证码下载到本地,手动输入验证码(以下例子采用这种方式)。

2.模拟登录的分析过程

  • 浏览器访问知乎 - 与世界分享你的知识、经验和见解知乎登录页面,然后右键审查元素(快捷键F12),选择network,把Preservre log选上,然后输入账号密码和验证码,点击登录。如果登录成功会重定向到知乎首页然后会有大量的请求了,这时找登录请求可能不方便。所以这里有个小技巧,故意把密码输错,这时候就不会重定向跳转了,就可以容易的找到登录请求。这里我用的邮箱登录。如下图

  • 现在要做的就是找到Form Data里面参数的来源,这里有4个参数分别是_xsrf,password,remember_me,email,_xsrf在登录页面源码里面能够找到,password就是你的密码,remember_me就是记住我那个复选框,email就是登录邮箱。经过测试_xsrf这个参数设置为“”空字符串也能登录成功,所以这个参数可以不用去获取。
  • 知乎登录的验证码。把验证码下载到本地,然后肉眼识别后手动输入。
  • 怎么验证是否成功登录知乎。提交登录请求后,知乎服务器会响应一段json,可以判断是否登录成功。

3.主要逻辑代码

以下是模拟登录知乎的主要逻辑代码
package com.wy;

import org.apache.http.NameValuePair;
import org.apache.http.client.config.COOKIESpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.COOKIE.COOKIESpecProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.COOKIE.BestMatchSpecFactory;
import org.apache.http.impl.COOKIE.BrowserCompatSpecFactory;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
* 模拟登录知乎
*/
public class Main {
//知乎首页
final private static String INDEX_URL = "https://www.zhihu.com";
//邮箱登录地址
final private static String EMAIL_LOGIN_URL = "https://www.zhihu.com/login/email";
//手机号码登录地址
final private static String PHONENUM_LOGIN_URL = "https://www.zhihu.com/login/phone_num";
//登录验证码地址
final private static String YZM_URL = "https://www.zhihu.com/captcha.gif?type=login";

private CloseableHttpClient httpClient;
private HttpClientContext httpClientContext;

/**
* 初始化CloseableHttpClient、HttpClientContext并设置COOKIE策略
*/
public Main(){
RequestConfig globalCOnfig= RequestConfig.custom()
.setCOOKIESpec(COOKIESpecs.BROWSER_COMPATIBILITY)
.build();
httpClient = HttpClients.custom()
.setDefaultRequestConfig(globalConfig)
.build();

httpClientCOntext= HttpClientContext.create();
Registry registry = RegistryBuilder
. create()
.register(COOKIESpecs.BEST_MATCH, new BestMatchSpecFactory())
.register(COOKIESpecs.BROWSER_COMPATIBILITY,
new BrowserCompatSpecFactory()).build();
httpClientContext.setCOOKIESpecRegistry(registry);
}
/**
*
* @param emailOrPhoneNum 邮箱或手机号码
* @param pwd 密码
* @return
*/
public boolean login(String emailOrPhoneNum,
String pwd){
String yzm = null;
String loginState = null;
HttpGet getRequest = new HttpGet(INDEX_URL);
HttpClientUtil.getWebPage(httpClient, httpClientContext, getRequest, "utf-8", false);
HttpPost request = null;
List formParams = new ArrayList();
if(emailOrPhoneNum.contains("@")){
//通过邮箱登录
request = new HttpPost(EMAIL_LOGIN_URL);
formParams.add(new BasicNameValuePair("email", emailOrPhoneNum));
}
else {
//通过手机号码登录
request = new HttpPost(PHONENUM_LOGIN_URL);
formParams.add(new BasicNameValuePair("phone_num", emailOrPhoneNum));
}
yzm = yzm(httpClient, httpClientContext, YZM_URL);
formParams.add(new BasicNameValuePair("captcha", yzm));
formParams.add(new BasicNameValuePair("_xsrf", ""));//这个参数可以不用
formParams.add(new BasicNameValuePair("password", pwd));
formParams.add(new BasicNameValuePair("remember_me", "true"));
UrlEncodedFormEntity entity = null;
try {
entity = new UrlEncodedFormEntity(formParams, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
request.setEntity(entity);
loginState = HttpClientUtil.getWebPage(httpClient, httpClientContext, request, "utf-8", false);//登录
JSONObject jo = new JSONObject(loginState);
if(jo.get("r").toString().equals("0")){
System.out.println("登录知乎成功");
getRequest = new HttpGet("https://www.zhihu.com");
/**
* 访问首页
*/
HttpClientUtil.getWebPage(httpClient, httpClientContext,getRequest, "utf-8", false);
return true;
}else{
throw new RuntimeException(HttpClientUtil.decodeUnicode(loginState));
}
}
/**
* 下载验证码至本地,并手动输入验证码
* @return
*/
public String yzm(CloseableHttpClient httpClient,HttpClientContext context, String url){
String verificatiOnCodePath= System.getProperty("user.home");
//下载验证码至本地
HttpClientUtil.downloadFile(httpClient, context, url, verificationCodePath, "/yzm.jpg",true);
System.out.println("请输入 " + verificationCodePath + "\\yzm.jpg 下的验证码:");
Scanner sc = new Scanner(System.in);
String yzm = sc.nextLine();
return yzm;
}
public static void main(String[] args){
Main modelLogin = new Main();
modelLogin.login("邮箱或手机号码", "密码");
}
}


完整工程下载地址

点击下载

有问题,欢迎评论区交流

推荐阅读
  • 深入探讨Web服务器与动态语言的交互机制:CGI、FastCGI与PHP-FPM
    本文详细解析了Web服务器(如Apache、Nginx等)与动态语言(如PHP)之间通过CGI、FastCGI及PHP-FPM进行交互的具体过程,旨在帮助开发者更好地理解这些技术背后的原理。 ... [详细]
  • 本文详细介绍了跨站脚本攻击(XSS)的基本概念、工作原理,并通过实际案例演示如何构建XSS漏洞的测试环境,以及探讨了XSS攻击的不同形式和防御策略。 ... [详细]
  • 本文探讨了在使用 ClickOnce 部署方式时遇到的自动更新失败问题,包括本地安装与服务器安装的不同表现,并提供了详细的解决方案。 ... [详细]
  • PHP网站部署指南:从零开始搭建PHP网站
    本文提供了详细的步骤指导,帮助开发者在不同环境下成功部署PHP网站,包括在IIS和Apache服务器上的具体操作。 ... [详细]
  • 解析 HTTP 头 'Vary: Accept-Encoding' 的作用与重要性
    本文详细探讨了 'Vary: Accept-Encoding' HTTP 头的作用,即指导缓存系统(如代理服务器和 CDN)根据不同的编码需求存储和提供适当的资源版本,确保不同类型的客户端能够接收到适合自己的内容。 ... [详细]
  • 微信小程序支付官方参数小程序中代码后端发起支付代码支付回调官方参数文档地址:https:developers.weixin.qq.comminiprogramdeva ... [详细]
  • 本文档提供了详细的MySQL安装步骤,包括解压安装文件、选择安装类型、配置MySQL服务以及设置管理员密码等关键环节,帮助用户顺利完成MySQL的安装。 ... [详细]
  • 本文介绍了多种Eclipse插件,包括XML Schema Infoset Model (XSD)、Graphical Editing Framework (GEF)、Eclipse Modeling Framework (EMF)等,涵盖了从Web开发到图形界面编辑的多个方面。 ... [详细]
  • 对于初次购买阿里云服务器的新手用户来说,如何高效地利用服务器资源并成功部署网站是一个重要的课题。本文将详细指导您完成从购买服务器到网站上线的六个关键步骤。 ... [详细]
  • 本文详细介绍了在 Windows 7 上安装和配置 PHP 5.4 的 Memcached 分布式缓存系统的方法,旨在减少数据库的频繁访问,提高应用程序的响应速度。 ... [详细]
  • 华为云openEuler环境下的Web应用部署实践
    本文详细记录了在华为云openEuler系统上进行Web应用部署的具体步骤,包括配置yum源、安装Apache、MariaDB、PHP及其相关组件,并完成WordPress的安装与配置过程。 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 解决JavaWeb项目中因IPv6导致的IP转换错误
    本文探讨了在JavaWeb项目中,当尝试将客户端IP地址从字符串形式转换为整数时遇到的问题,并提供了详细的解决方案。具体问题表现为在本地环境中通过`request.getRemoteHost()`获取到的IP地址为IPv6格式,而非预期的IPv4格式。 ... [详细]
  • 本文探讨了在使用Apache Flink向Kafka发送数据过程中遇到的事务频繁失败问题,并提供了详细的解决方案,包括必要的配置调整和最佳实践。 ... [详细]
  • 本文详细介绍了如何在 EasyUI 框架中实现 DataGrid 组件的分页功能,包括配置方法和常见问题的解决方案。 ... [详细]
author-avatar
漂亮女人群
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有