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

PS:很多人咨询我怎么做手机群控系统,因此我开了个制作群控系统的系列,准备分五期讲解群控系统的制作。前两篇是基础内容。

今天做个简单的java模拟登录网页版微信。

既然要做模拟登录,那么我们一定要了解整个登录过程,我们这就来真实操作一遍:当我们登录网页版微信后会出现个扫码登录的窗口,我们扫码二维码成功后就跳转到登录成功页面并重定向到网页版微信。

那么我们的目标是做一个工具,当启动会帮我们调用微信的二维码接口,下载二维码图片,然后在后台展示二维码让我们扫码,扫码成功后跳转到网页版微信。

梳理后我们将进行下面的动作:

1 获取二维码

2 下载图片

3 弹出二维码扫码框

4 检查是否登录

5 登录网页版

请求的地址就直接贴出来了,需要的自行抓包(可以使用charles,fiddler,鲨鱼,浏览器F12)

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;

/**
 * @
作者: LYB
 * @创建日期: 2018/9/25
 * @描述: 模拟登录网页版微信
 */

public class WeixinLogin {
   
//=====================================请求地址==========================================
   
static String WEIXIN_LOGIN_URL = "https://wx.qq.com/";//初始化请求地址
   
static String APID_URL         = "https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_=";//获取appid请求地址
   
static String QRCODE_URL       = "https://login.weixin.qq.com/qrcode/";//获取二维码地址
    //=====================================请求地址==========================================
    //=====================================变量存储==========================================
   
static CloseableHttpClient https = HttpClients.createDefault();
   
static String LOGIN_URL = "";
   
static String qrCodeUrl = "";
   
static String appid = "";
   
public static Boolean isScan = false;
   
//=====================================变量存储==========================================
    //第一步:获取二维码完整地址
   
public static String getQrCodeURL() {
       
try {
           
//1 拿到登录页面
           
HttpGet httpGet = new HttpGet(WEIXIN_LOGIN_URL);
            HttpResponse loginResp =
https.execute(httpGet);
            HttpEntity loginEntitySort = loginResp.getEntity();
            String loginPage = EntityUtils.toString(loginEntitySort,
"utf-8");
           
//2 获取appid 根据抓包可知道要拿到二维码需要先请求获取appid
           
String url = APID_URL + System.currentTimeMillis();
            HttpGet httpPost =
new HttpGet(url);
            HttpResponse response =
https.execute(httpPost);
            HttpEntity entitySort = response.getEntity();
            String html = EntityUtils.toString(entitySort,
"utf-8");
           
//发送请求拿到的是串window.QRLogin.code = 200; window.QRLogin.uuid = 'XXX'的字符串,而xxx就是appid
           
if (html.indexOf("window.QRLogin.code = 200") != -1) {
               
appid = html.replace("window.QRLogin.code = 200; window.QRLogin.uuid = \"", "").replace("\";", "");
            }

           
//3 获取二维码地址 获取二维码地址需要拼接appid后请求得到
           
String codeUrl = QRCODE_URL + appid;
            HttpGet httpget =
new HttpGet(codeUrl);
           
qrCodeUrl = httpget.getURI().toString();
            System.
out.println("获取到的二维码地址是:" + qrCodeUrl);//开始
           
return qrCodeUrl;
        }
catch (Exception e) {
           
return null;

        }
    }

   
//第二步:下载图片 拿到地址后下一步就是下载图片啦(其实可以不下载的,直接在Swing中展示),下载的代码就不说了,也懒得优化。
   
private static void downloadPicture(String imgURL, String path) {
        URL url =
null;
        FileOutputStream fileOutputStream =
null;
        DataInputStream dataInputStream =
null;
        ByteArrayOutputStream output =
null;
       
try {
            url =
new URL(imgURL);
            dataInputStream =
new DataInputStream(url.openStream());

            fileOutputStream =
new FileOutputStream(new File(path));
            output =
new ByteArrayOutputStream();

           
byte[] buffer = new byte[1024];
           
int length;

           
while ((length = dataInputStream.read(buffer)) > 0) {
                output.write(buffer,
0, length);
            }
            fileOutputStream.write(output.toByteArray());
            dataInputStream.close();
            fileOutputStream.close();
        }
catch (MalformedURLException e) {
            e.printStackTrace();
        }
catch (IOException e) {
            e.printStackTrace();
        }
finally {//千万记得关闭流
           
org.apache.commons.io.IOUtils.closeQuietly(fileOutputStream);
            org.apache.commons.io.IOUtils.closeQuietly(dataInputStream);
            org.apache.commons.io.IOUtils.closeQuietly(output);
        }
    }

   
//第三步:将二维码在后台展示
   
public static Boolean showQrCode() {
       
//为了后面main方便调用先将前面两步方法引入代码中
        //第一步: 获取二维码地址
       
if(qrCodeUrl.equals("")){
           
qrCodeUrl = getQrCodeURL();
        }
       
//第二步: 下载二维码图片
       
String downLoadHere = "C:\\Users\\abc\\Desktop\\qrCode.png";
        downloadPicture(
qrCodeUrl, downLoadHere);
       
//第三步开始
        //1 配置后台二维码展示窗口
       
final JFrame frame = new JFrame("请扫描二维码完成登录");
       
//设置frame窗口
       
frame.setSize(550, 550);
        frame.setLocation(
580, 200);
        frame.setLayout(
null);

        JLabel label =
new JLabel();

       
//2 根据图片创建ImageIcon对象
       
ImageIcon imageIcon = new ImageIcon(downLoadHere);
       
//设置ImageIcon
       
label.setIcon(imageIcon);
       
//label的大小设置为ImageIcon,否则显示不完整
       
label.setBounds(50, 50, imageIcon.getIconWidth(), imageIcon.getIconHeight());
       
//将label放入frame
       
frame.add(label);
        frame.setDefaultCloseOperation(JFrame.
EXIT_ON_CLOSE);
        frame.setVisible(
true);
       
//3 添加button按钮 当用户扫码完点击之后关闭扫码窗口
       
JButton button = new JButton("扫描完请点击");
        button.setBounds(
210, 460, 120, 30);
        button.addActionListener(
new ActionListener() {
           
@Override
           
public void actionPerformed(ActionEvent arg0) {
               
frame.dispose();
                System.
out.println("关闭扫码窗口!");
                WeixinLogin.
isScan=true;
            }
        });
        frame.add(button);
       
return isScan;
    }

   
//第四步: 检查是否登录  关闭扫码窗口后需要判断是否登录了
   
public static int checklogin()
    {
       
if(appid.equals("")){
           
appid = getQrCodeURL();
        }
       
//1 配置爬虫:这里模拟的是谷歌浏览器 其它请求头是抓包拿到的,没具体校验是否都需要
        //抓包拿到的检验登录的地址,不提取出去了。
       
String url="https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid="+appid+"&tip=0&r=123&_="+System.currentTimeMillis();//检查登录地址
       
HttpGet httpPost=new HttpGet(url);
        httpPost.setHeader(
"Host", "login.wx.qq.com");
        httpPost.setHeader(
"Pragma", "no-cache");
        httpPost.setHeader(
"Referer", "https://wx.qq.com/");
        httpPost.setHeader(
"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
        httpPost.setHeader(
"Connection", "keep-alive");
       
int timeout = 200000;//设置超时时间

       
RequestConfig config = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout)
                .setConnectionRequestTimeout(timeout).build();
        httpPost.setConfig(config);
       
//2 发送请求判断是否登录 返回的是window.code = xxx的字符串,xxx是200证明登录成功
       
String html="";
       
try {
            HttpResponse response =
https.execute(httpPost);
            HttpEntity entitySort = response.getEntity();
            html=EntityUtils.toString(entitySort,
"utf-8");
           
//System.out.println("检查登录回调内容: "+html);
           
if(html.indexOf("408")!=-1)
            {
               
return 1;
            }
           
if(html.indexOf("400")!=-1)
            {
               
return 2;
            }
           
if(html.indexOf("200")!=-1)
            {
               
//3 登录成功拼接登录地址
               
int start=html.indexOf("https");
                html=html.substring(start).replace(
"\";", "");
               
LOGIN_URL=html;
                System.
out.println("成功登录,登录地址: "+LOGIN_URL);
               
return 3;
            }
        }
catch (ClientProtocolException e) {

            e.printStackTrace();
        }
catch (IOException e) {
            e.printStackTrace();
        }
       
return 0;
    }

   
public static void login()
    {
        HttpGet httpPost=
new HttpGet(LOGIN_URL);
        httpPost.setHeader(
"Host", "wx.qq.com");
        httpPost.setHeader(
"Pragma", "no-cache");
        httpPost.setHeader(
"Referer", "https://wx.qq.com/?&lang=zh_CN");
        httpPost.setHeader(
"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
        httpPost.setHeader(
"Connection", "keep-alive");
        String html=
"";
       
try {
            HttpResponse response =
https.execute(httpPost);
            HttpEntity entitySort = response.getEntity();
            html= EntityUtils.toString(entitySort,
"utf-8");
           
//System.out.println("登录成功回调: "+html);

       
} catch (ClientProtocolException e) {

            e.printStackTrace();
        }
catch (IOException e) {
            e.printStackTrace();
        }

    }

   
//第五步: 在浏览器打开登录后的地址 最后步登录成功后我们调用浏览器打开登录页面
   
public static void openLoginPage() {
       
try {
            Desktop desk=Desktop.getDesktop();
            URI path=
new URI(LOGIN_URL);
            desk.browse(path);
        }
catch (Exception e) {
            System.
out.println("打开异常!");
        }
    }

   
public static void main(String[] args) {
       
//展示二维码:包含第一二三步
       
Boolean isScan = showQrCode();
       
for(int i=0;;i++)
        {
           
//校验是否登录
           
int cf=checklogin();
           
if(cf==3)
            {
               
//如果登录就打开二维码
               
openLoginPage();//打开
               
break;
            }
           
if(cf==2)
            {
               
//如果没登录就重新打卡二维码
               
System.out.println("未扫码二维码,正在重试!");
                showQrCode();
            }
           
if(cf==1)
            {
               
continue;
            }
           
try {
                Thread.sleep(
13000);
            }
catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 

你可能感兴趣的:(群控系统)