Java模拟web微x登录发送文字和图片消息简单实现爬虫

先说需求!有很多人是在做微商的,要是你把你的产品发到朋友圈,你所发的内容是有可能被掩盖掉的!就是我们再使用手机版微信APP的时候,群发是有一定人数限制的(这些都是废话和铺垫),这个时候就想到是不是可以用Java模拟web微Xin,写个程序(后来知道,居然大家管这个东西叫机器人),然后发送消息,就可以解决了。

    作为程序猿的利器,chrome和fiddler,说做就做(其实是对web微信协议的自己分析)。

1.获取二维码:这肯定是最开始需要的

web版地址是这个 https://wx.qq.com/,打开这个地址,F12一下,


这里我们看到加载了一大堆的js和图片,我们关心的只要是标红的三个就好了

1.1 获取UUID换取二维码

 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&_=1497430023830

这个方法是第一步,jslogin 这是个get的请求方法,这个我们可以看他所需要的请求参数有4个

  1. appid:
    wx782c26e4c19acffb
  2. redirect_uri:
    https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage
  3. fun:
    new
  4. lang:
    zh_CN
  5. _:
    1497430023830
我开始做的时候,不管怎么通过F12查看有返回appid的方法都没有找到,后来我试了其他的微信号,发现这个appid都一样,所以告诉大家,这个appid是固定的!至于149开头的那个参数就很好猜了,就是时间戳,其他参数同样固定。

这个请求发返回结果是这样的

window.QRLogin.code = 200; window.QRLogin.uuid = "QY6pTM6Avw==";

我们再来对照F12下面的看下,


是不是发现了,这两个的值是一样的!jslogin返回的uuid,就是我们置换二维码的参数,刷新下页面,我们再看

1.2获取二维码

https://login.weixin.qq.com/qrcode/4aJWOM4Jpw==

这个方法同样是get请求,没有参数


这时候我们就可以在响应看到我们的二维码了,


这个时候是response是没值的,但是我们可以通过preview预显示看到二维码,这是因为这个响应结果是以流的形式返回的,我们只需要将流生成响应的图片就好了。

1.3长轮询判断手机端

https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=AaSwnCS2UQ==&tip=0&r=1512572422&_=1497430963219

请求方式是get

请求参数是

  1. loginicon:
    true
  2. uuid:
    AaSwnCS2UQ==
  3. tip:
    0
  4. r:
    1512572422
  5. _:
    1497430963219

参数解释,其中loginicon、tip是固定参数,uuid是jslogin返回的值,和换取二维码参数一样;_是时间戳;r这个参数,网上很多人说取反,我自己用Java代码亲测是不对的,没有使用js测试,因为js不是太熟悉,我可以明确告诉你们r=_/760,就是时间戳/760,就是参数r。

返回结果是 window.code=408;

我们看到这个方法一直在做长轮询,25秒左右一次,返回结果就是window.code=408;这个是一直发送的请求,是告诉你,服务器没有收到你的扫码或者扫码之后的登录确定;当然,这个扫码和确定登录时需要手机端配合的。

1.4长轮询判断手机端获取头像

https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=QbQnDRrWjg==&tip=0&r=1511576646&_=1497431985392

再看这个请求,长轮询一直进行,参数和上面一样,当我们用手机扫码之后这时候再看返回结果

window.code=201;window.userAvatar = 'data:img/jpg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/2wBDAAMCAgMCAgM..........'

code=201 然后后面紧跟的是个base64,这个大家肯定熟悉了,这个就是你自己微信的头像,这样我们就可以拿到自己的微信头像,这时候大家要知道的是返回code是201,

1.5长轮询判断手机端

https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=QbQnDRrWjg==&tip=0&r=1511570443&_=1497431985393

还在继续这个请求,我用自己的手机扫码之后,然后手机锁屏,这时候,我没有点击手机上的确认登录,我们看到


这个请求还在一直继续,然后返回的结果还是408,我们接着往下做。

1.6长轮询判断手机端确认登录

https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=QbQnDRrWjg==&tip=0&r=1511545371&_=1497431985394

继续这个请求,和上面几个方法一样,也是get请求,参数都和1.3一样。我这时候在手机端点击确认登录网页版


这个时候我们看到有新的返回,code是200了,然后还有个redirect_uri 重定向地址返回给我们,这个是个很重要的地址,也很符合mp文档的规范,使用ticket作为下次的请求,这个地址我们先不拆开,直接作为下次使用的参数

1.7初始化页面得到关键参数

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=.....&uuid=QbQnDRrWjg==&lang=zh_CN&scan=1497432010&fun=new&version=v2&lang=zh_CN

我这边把ticket去掉用....代替,地址就是1.6返回的URI再在后面拼接fun、version、lang构成,

这个请求同样是get请求,

请求参数可以直接在地址后面拼接就好

返回参数;

对这个请求是整个web微信中至关重要的一步,我做的时候就是这一步没有认真,返回参数如下


这里的返回skey,pass_ticket,wxsid,wxuin这些参数都会在后面的请求中使用到;在这里先漏讲2个重要的地方;后面大家有使用发现问题的时候可以直接问我,这2个点非常非常重要。可能有些人也能悟的出来

1.8 微信数据初始化

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=1511600827&lang=zh_CN&pass_ticket=...

这里的pass_ticket我同样使用...代替;

请求方式为 post

请求参数

  1. {,…}
    1. BaseRequest:{Uin: "...", Sid: "...", Skey: "...",…}
      1. DeviceID:"e027437096416987"
      2. Sid:"...."
      3. Skey:"....."
      4. Uin:"...."

这个请求参数相信做个后端的看得懂吧!其中deviceId是e+随机数(长度固定,自己数吧),这个就是json方式的请求,同样的这些参数是来自上一步返回的参数解析出来的值;

再看返回结果:


这儿是返回你最近联系的人的信息,其中User是你自己的个人信息,其中nickname是昵称的意思,我们暂时先知道这么多,user其中的username是自己在微信中发消息所使用的得名字,我们需要把这个解析出来;

1.9开启微信接收消息通知状态

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify?lang=zh_CN&pass_ticket=...

请求方式post

请求参数

  1. {,…}
    1. BaseRequest:{Uin: ..., Sid: "...", Skey: "...",…}
      1. DeviceID:"..."e+固定长度随机数
      2. Sid:"...."前面返回
      3. Skey:"...."前面返回
      4. Uin:...前面返回
    2. ClientMsgId:时间戳
    3. Code:3
    4. FromUserName:"上一步User中的username,就是自己的username"
    5. ToUserName:"上一步User中的username,就是自己的username"


返回参数

{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
}
,
"MsgID": "..."
}

这个是正确的返回参数,其中MsgID是下面所需要用到的;这里的请求也需要用到上面漏讲的重要2点的内容。

2.0获取联系人

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=...&seq=0&skey=...

这一步使我们要获取我们发送消息的先决条件,***(在这还有个获取最近联系人的方法

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxbatchgetcontact?type=ex&r=1497432043736&lang=zh_CN&pass_ticket=...

只需要pass_ticket就可以,请求方式post,这是网上很多人所说的获取联系人,这个我不推荐,和我们的出发点很远,也不好用

***

请求方式get

请求参数直接拼接就好

返回数据预览

  1. {BaseResponse: {Ret: 0, ErrMsg: ""}, MemberCount: 419,…}
    1. BaseResponse:{Ret: 0, ErrMsg: ""}
    2. MemberCount:419
    3. MemberList:[{Uin: 0, UserName: "...",…},…]
    4. Seq:0
这样是以json返回,其中memberlist是我们所要关心的,我们需要其中的username,至于其中其他的参数的含义我们暂时不管,网上有很多解读,其中的count是我们获取到的联系人的数量,我有419个;

2.1置换图片mediaId

https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json

这里我们先说置换图片mediaId,网上大部分人都没有把这个说清楚,当时我去请教别人的时候,别人是要收我钱才肯告诉我的;

请求方式post

请求参数 使用fiddler拦截抓包这样就很清晰了吧


这样够清晰了,这个就是一个form带文件的表单提交,其中各个对应的参数我们需要自己构建,最终是以json的形式发送,其中

uploadmediarequest这个参数较为特殊,我一样使用...代替重要参数

{"UploadType":2,"BaseRequest":{"Uin":408216280,"Sid":"...","Skey":"...","DeviceID":"..."},"ClientMediaId":1497435635161,"TotalLen":318889,"StartPos":0,"DataLen":318889,"MediaType":4,"FromUserName":"...","ToUserName":"filehelper","FileMd5":"12dc0221652975df9723aae462794d77"}

相信大家看的懂,稍微解释一下,UploadType是上传的文件类型2,ClientMediaId时间戳,FromUserName自己的账号,ToUserName发送对象的账号,FileMd5这个也是我请教别人的点,他居然告诉我写死,我自己研究了下,可以明确告诉大家,那家伙瞎说,这个就是文件的MD5,MediaType也是固定的4,剩下的参数应该不是难度了,至于抓包出现的有个参数前面没有出现,我暂时也不解释;

返回参数

{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
}
,
"MediaId": "...",
"StartPos": 318889,
"CDNThumbImgHeight": 56,
"CDNThumbImgWidth": 100
}

其中的mediaId就是我们发送图片时所需要的参数

2.2发送图片消息

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg?fun=async&f=json&lang=zh_CN&pass_ticket=...

请求方式post

请求参数

  1. {,…}
    1. BaseRequest:{Uin: 408216280, Sid: "...", Skey: "...",…}
      1. DeviceID:"e069704885012937"
      2. Sid:"..."
      3. Skey:".."
      4. Uin:408216280
    2. Msg:{Type: 3,…}
      1. ClientMsgId:"14974356351610395"时间戳+4位随机数
      2. Content:""空着
      3. FromUserName:"..."自己的username
      4. LocalID:"14974356351610395" 时间戳+4位随机数
      5. MediaId:"..."上面上传图片返回
      6. ToUserName:"filehelper"接收方的username
      7. Type:3 固定值
    3. Scene:0
这边稍微解释下,如上注释

返回参数

{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
}
,
"MsgID": "...",
"LocalID": "..."
}

当ret为0的时候这样我们就发送成功,这边我们以发送图片为例,暂时发送文字消息还有其他的消息就很简单了!

2.3心跳包

https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck?r=1497436739199&skey=...&uin=408216280&deviceid=...&synckey=...

心跳包

请求方式get

每个25秒做一次请求

返回参数

window.synccheck={retcode:"0",selector:"0"}

这边就不对其做深入讲解,网上有着总结好的内容!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值