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"}

這邊就不對其做深入講解,網上有着總結好的內容!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章