時間:2022-07-24 01:18:01 | 來源:網站運營
時間:2022-07-24 01:18:01 來源:網站運營
2019年10月28日更新:http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MjM5MzczNjY2NA==#wechat_webview_type=1&wechat_redirect
=========2017年1月11日更新=========https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzA3NDk5MjYzNg==&scene=124#wechat_redirect
//第一種鏈接http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MjM5NTM1NjczMw==&uin=NzM4MTk1ODgx&key=a226a081696afed0d9dfa0972fa431e116e5c4572ce52343178ad4e9a2b94aeaad6ac4dd87de3e56f72209a73a32e9cc2052f68aca4884e36cf726e99f2671630c741d8e4c29abe4a049d1a71eeb2be5&devicetype=android-17&version=2605033c&lang=zh_CN&nettype=WIFI&ascene=1&pass_ticket=zbA7PswOPKySRpyEYI5kDCjRiljxcpzdbTuVMauFGemgdp8R1DY1uQY49srehWab&wx_header=1//第二種http://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzA3NDk5MjYzNg==&scene=124&uin=NzM4MTk1ODgx&key=5134ab1cc362a0324183dbd55a2680d11ccbaa34cdb349ee9be58f5b666092ddb17adf8a88dc788831923f3c6087547d651f04209f72334d511c9e118a3800d7b05a324a38903f79cff940cf749ecd5a&devicetype=android-17&version=2605033c&lang=zh_CN&nettype=WIFI&a8scene=3&pass_ticket=Fo3zjtJcbPfijNHKUIQbV%2BeHsAqhbjJCwzTfV48u%2FCZRRGTmI8oqmHDxxfEL8ke%2B&wx_header=1
這個地址是通過微信客戶端打開歷史消息頁面之后,再使用后面介紹的代理服務器軟件獲取到的。這里面有幾個參數(shù):replaceServerResDataAsync: function(req,res,serverResData,callback){ if(/mp//getmasssendmsg/i.test(req.url)){//當鏈接地址為公眾號歷史消息頁面時(第一種頁面形式) if(serverResData.toString() !== ""){ try {//防止報錯退出程序 var reg = /msgList = (.*?);/;//定義歷史消息正則匹配規(guī)則 var ret = reg.exec(serverResData.toString());//轉換變量為string HttpPost(ret[1],req.url,"getMsgJson.php");//這個函數(shù)是后文定義的,將匹配到的歷史消息json發(fā)送到自己的服務器 var http = require('http'); http.get('http://xxx.com/getWxHis.php', function(res) {//這個地址是自己服務器上的一個程序,目的是為了獲取到下一個鏈接地址,將地址放在一個js腳本中,將頁面自動跳轉到下一頁。后文將介紹getWxHis.php的原理。 res.on('data', function(chunk){ callback(chunk+serverResData);//將返回的代碼插入到歷史消息頁面中,并返回顯示出來 }) }); }catch(e){//如果上面的正則沒有匹配到,那么這個頁面內容可能是公眾號歷史消息頁面向下翻動的第二頁,因為歷史消息第一頁是html格式的,第二頁就是json格式的。 try { var json = JSON.parse(serverResData.toString()); if (json.general_msg_list != []) { HttpPost(json.general_msg_list,req.url,"getMsgJson.php");//這個函數(shù)和上面的一樣是后文定義的,將第二頁歷史消息的json發(fā)送到自己的服務器 } }catch(e){ console.log(e);//錯誤捕捉 } callback(serverResData);//直接返回第二頁json內容 } } }else if(/mp//profile_ext/?action=home/i.test(req.url)){//當鏈接地址為公眾號歷史消息頁面時(第二種頁面形式) try { var reg = /var msgList = /'(.*?)/';/;//定義歷史消息正則匹配規(guī)則(和第一種頁面形式的正則不同) var ret = reg.exec(serverResData.toString());//轉換變量為string HttpPost(ret[1],req.url,"getMsgJson.php");//這個函數(shù)是后文定義的,將匹配到的歷史消息json發(fā)送到自己的服務器 var http = require('http'); http.get('http://xxx.com/getWxHis', function(res) {//這個地址是自己服務器上的一個程序,目的是為了獲取到下一個鏈接地址,將地址放在一個js腳本中,將頁面自動跳轉到下一頁。后文將介紹getWxHis.php的原理。 res.on('data', function(chunk){ callback(chunk+serverResData);//將返回的代碼插入到歷史消息頁面中,并返回顯示出來 }) }); }catch(e){ callback(serverResData); } }else if(/mp//profile_ext/?action=getmsg/i.test(req.url)){//第二種頁面表現(xiàn)形式的向下翻頁后的json try { var json = JSON.parse(serverResData.toString()); if (json.general_msg_list != []) { HttpPost(json.general_msg_list,req.url,"getMsgJson.php");//這個函數(shù)和上面的一樣是后文定義的,將第二頁歷史消息的json發(fā)送到自己的服務器 } }catch(e){ console.log(e); } callback(serverResData); }else if(/mp//getappmsgext/i.test(req.url)){//當鏈接地址為公眾號文章閱讀量和點贊量時 try { HttpPost(serverResData,req.url,"getMsgExt.php");//函數(shù)是后文定義的,功能是將文章閱讀量點贊量的json發(fā)送到服務器 }catch(e){ } callback(serverResData); }else if(/s/?__biz/i.test(req.url) || /mp//rumor/i.test(req.url)){//當鏈接地址為公眾號文章時(rumor這個地址是公眾號文章被辟謠了) try { var http = require('http'); http.get('http://xxx.com/getWxPost.php', function(res) {//這個地址是自己服務器上的另一個程序,目的是為了獲取到下一個鏈接地址,將地址放在一個js腳本中,將頁面自動跳轉到下一頁。后文將介紹getWxPost.php的原理。 res.on('data', function(chunk){ callback(chunk+serverResData); }) }); }catch(e){ callback(serverResData); } }else{ callback(serverResData); } },
function HttpPost(str,url,path) {//將json發(fā)送到服務器,str為json內容,url為歷史消息頁面地址,path是接收程序的路徑和文件名 var http = require('http'); var data = { str: encodeURIComponent(str), url: encodeURIComponent(url) }; content = require('querystring').stringify(data); var options = { method: "POST", host: "www.xxx.com",//注意沒有http://,這是服務器的域名。 port: 80, path: path,//接收程序的路徑和文件名 headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', "Content-Length": content.length } }; var req = http.request(options, function (res) { res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('BODY: ' + chunk); }); }); req.on('error', function (e) { console.log('problem with request: ' + e.message); }); req.write(content); req.end();}
上面就是rule規(guī)則修改的主要部分,需要將json內容發(fā)送到自己的服務器,還要從服務器獲取到下一頁的跳轉地址。這就涉及到了四個php文件:getMsgJson.php、getMsgExt.php、getWxHis.php、getWxPost.phpreplaceRequestOption : function(req,option){ var newOption = option; if(/google/i.test(newOption.headers.host)){ newOption.hostname = "www.baidu.com"; newOption.port = "80"; } return newOption; },
以上就是針對anyproxy的rule文件的修改配置,配置修改完成之后,重新啟動anyproxy。mac系統(tǒng)里按control+c中斷程序,再輸入命令sudo anyproxy -i啟動;如果啟動報錯,可能是程序沒有退出干凈,端口被占用。這時輸入命令ps -a查看占用的pid,再輸入命令“kill -9 pid”這里將pid替換成查詢到的pid號碼。殺死進程之后就可以啟動anyproxy了。還是那句話windows的命令請原諒我不太熟悉。<?$str = $_POST['str'];$url = $_POST['url'];//先獲取到兩個POST變量//先針對url參數(shù)進行操作parse_str(parse_url(htmlspecialchars_decode(urldecode($url)),PHP_URL_QUERY ),$query);//解析url地址$biz = $query['__biz'];//得到公眾號的biz//接下來進行以下操作//從數(shù)據(jù)庫中查詢biz是否已經存在,如果不存在則插入,這代表著我們新添加了一個采集目標公眾號。//再解析str變量$json = json_decode($str,true);//首先進行json_decodeif(!$json){ $json = json_decode(htmlspecialchars_decode($str),true);//如果不成功,就增加一步htmlspecialchars_decode}foreach($json['list'] as $k=>$v){ $type = $v['comm_msg_info']['type']; if($type==49){//type=49代表是圖文消息 $content_url = str_replace("//", "", htmlspecialchars_decode($v['app_msg_ext_info']['content_url']));//獲得圖文消息的鏈接地址 $is_multi = $v['app_msg_ext_info']['is_multi'];//是否是多圖文消息 $datetime = $v['comm_msg_info']['datetime'];//圖文消息發(fā)送時間 //在這里將圖文消息鏈接地址插入到采集隊列庫中(隊列庫將在后文介紹,主要目的是建立一個批量采集隊列,另一個程序將根據(jù)隊列安排下一個采集的公眾號或者文章內容) //在這里根據(jù)$content_url從數(shù)據(jù)庫中判斷一下是否重復 if('數(shù)據(jù)庫中不存在相同的$content_url') { $fileid = $v['app_msg_ext_info']['fileid'];//一個微信給的id $title = $v['app_msg_ext_info']['title'];//文章標題 $title_encode = urlencode(str_replace(" ", "", $title));//建議將標題進行編碼,這樣就可以存儲emoji特殊符號了 $digest = $v['app_msg_ext_info']['digest'];//文章摘要 $source_url = str_replace("//", "", htmlspecialchars_decode($v['app_msg_ext_info']['source_url']));//閱讀原文的鏈接 $cover = str_replace("//", "", htmlspecialchars_decode($v['app_msg_ext_info']['cover']));//封面圖片 $is_top = 1;//標記一下是頭條內容 //現(xiàn)在存入數(shù)據(jù)庫 echo "頭條標題:".$title.$lastId."/n";//這個echo可以顯示在anyproxy的終端里 } if($is_multi==1){//如果是多圖文消息 foreach($v['app_msg_ext_info']['multi_app_msg_item_list'] as $kk=>$vv){//循環(huán)后面的圖文消息 $content_url = str_replace("//","",htmlspecialchars_decode($vv['content_url']));//圖文消息鏈接地址 //這里再次根據(jù)$content_url判斷一下數(shù)據(jù)庫中是否重復以免出錯 if('數(shù)據(jù)庫中不存在相同的$content_url'){ //在這里將圖文消息鏈接地址插入到采集隊列庫中(隊列庫將在后文介紹,主要目的是建立一個批量采集隊列,另一個程序將根據(jù)隊列安排下一個采集的公眾號或者文章內容) $title = $vv['title'];//文章標題 $fileid = $vv['fileid'];//一個微信給的id $title_encode = urlencode(str_replace(" ","",$title));//建議將標題進行編碼,這樣就可以存儲emoji特殊符號了 $digest = htmlspecialchars($vv['digest']);//文章摘要 $source_url = str_replace("//","",htmlspecialchars_decode($vv['source_url']));//閱讀原文的鏈接 //$cover = getCover(str_replace("//","",htmlspecialchars_decode($vv['cover']))); $cover = str_replace("//","",htmlspecialchars_decode($vv['cover']));//封面圖片 //現(xiàn)在存入數(shù)據(jù)庫 echo "標題:".$title.$lastId."/n"; } } } } }?>
再次強調代碼只是原理,其中一部分注視的代碼要自己編寫。<?$str = $_POST['str'];$url = $_POST['url'];//先獲取到兩個POST變量//先針對url參數(shù)進行操作parse_str(parse_url(htmlspecialchars_decode(urldecode($url)),PHP_URL_QUERY ),$query);//解析url地址$biz = $query['__biz'];//得到公眾號的biz$sn = $query['sn'];//再解析str變量$json = json_decode($str,true);//進行json_decode//$sql = "select * from `文章表` where `biz`='".$biz."' and `content_url` like '%".$sn."%'" limit 0,1;//根據(jù)biz和sn找到對應的文章$read_num = $json['appmsgstat']['read_num'];//閱讀量$like_num = $json['appmsgstat']['like_num'];//點贊量//在這里同樣根據(jù)sn在采集隊列表中刪除對應的文章,代表這篇文章可以移出采集隊列了//$sql = "delete from `隊列表` where `content_url` like '%".$sn."%'" //然后將閱讀量和點贊量更新到文章表中。exit(json_encode($msg));//可以顯示在anyproxy的終端里?>
3、getWxHis.php、getWxPost.php兩個程序比較類似,一起介紹<?//getWxHis.php 當前頁面為公眾號歷史消息時,讀取這個程序//在采集隊列表中有一個load字段,當值等于1時代表正在被讀取//首先刪除采集隊列表中l(wèi)oad=1的行//然后從隊列表中任意select一行if('隊列表為空'){ //隊列表如果空了,就從存儲公眾號biz的表中取得一個biz,這里我在公眾號表中設置了一個采集時間的time字段,按照正序排列之后,就得到時間戳最小的一個公眾號記錄,并取得它的biz $url = "http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=".$biz."#wechat_webview_type=1&wechat_redirect";//拼接公眾號歷史消息url地址(第一種頁面形式) $url = "https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=".$biz."&scene=124#wechat_redirect";//拼接公眾號歷史消息url地址(第二種頁面形式) //更新剛才提到的公眾號表中的采集時間time字段為當前時間戳。}else{ //取得當前這一行的content_url字段 $url = $content_url; //將load字段update為1}echo "<script>setTimeout(function(){window.location.href='".$url."';},2000);</script>";//將下一個將要跳轉的$url變成js腳本,由anyproxy注入到微信頁面中。?><?//getWxPost.php 當前頁面為公眾號文章頁面時,讀取這個程序//首先刪除采集隊列表中l(wèi)oad=1的行//然后從隊列表中按照“order by id asc”選擇多行(注意這一行和上面的程序不一樣) if(!empty('隊列表') && count('隊列表中的行數(shù)')>1){//(注意這一行和上面的程序不一樣) //取得第0行的content_url字段 $url = $content_url; //將第0行的load字段update為1 }else{ //隊列表還剩下最后一條時,就從存儲公眾號biz的表中取得一個biz,這里我在公眾號表中設置了一個采集時間的time字段,按照正序排列之后,就得到時間戳最小的一個公眾號記錄,并取得它的biz $url = "http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=".$biz."#wechat_webview_type=1&wechat_redirect";//拼接公眾號歷史消息url地址(第一種頁面形式) $url = "https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=".$biz."&scene=124#wechat_redirect";//拼接公眾號歷史消息url地址(第二種頁面形式) //更新剛才提到的公眾號表中的采集時間time字段為當前時間戳。 } echo "<script>setTimeout(function(){window.location.href='".$url."';},2000);</script>";//將下一個將要跳轉的$url變成js腳本,由anyproxy注入到微信頁面中。?>
這兩段程序的意義是:從隊列表中讀取出下一個采集內容的信息,如果是歷史消息頁,則將biz拼接到地址中(注意:評論區(qū)有朋友以為key和pass_ticket也要拼接,實則不需要),通過js的方式輸出到頁面,如果下一條是文章,則將歷史消息列表json中的文章地址直接輸出為js。同樣文章內容的地址中不包含uin和key這樣的參數(shù),這些參數(shù)都是由客戶端自動補充的。CREATE TABLE `weixin` ( `id` int(11) NOT NULL AUTO_INCREMENT, `biz` varchar(255) DEFAULT '' COMMENT '公眾號唯一標識biz', `collect` int(11) DEFAULT '1' COMMENT '記錄采集時間的時間戳', PRIMARY KEY (`id`)) ;
2、微信文章表CREATE TABLE `post` ( `id` int(11) NOT NULL AUTO_INCREMENT, `biz` varchar(255) CHARACTER SET utf8 NOT NULL COMMENT '文章對應的公眾號biz', `field_id` int(11) NOT NULL COMMENT '微信定義的一個id,每條文章唯一', `title` varchar(255) NOT NULL DEFAULT '' COMMENT '文章標題', `title_encode` text CHARACTER SET utf8 NOT NULL COMMENT '文章編碼,防止文章出現(xiàn)emoji', `digest` varchar(500) NOT NULL DEFAULT '' COMMENT '文章摘要', `content_url` varchar(500) CHARACTER SET utf8 NOT NULL COMMENT '文章地址', `source_url` varchar(500) CHARACTER SET utf8 NOT NULL COMMENT '閱讀原文地址', `cover` varchar(500) CHARACTER SET utf8 NOT NULL COMMENT '封面圖片', `is_multi` int(11) NOT NULL COMMENT '是否多圖文', `is_top` int(11) NOT NULL COMMENT '是否頭條', `datetime` int(11) NOT NULL COMMENT '文章時間戳', `readNum` int(11) NOT NULL DEFAULT '1' COMMENT '文章閱讀量', `likeNum` int(11) NOT NULL DEFAULT '0' COMMENT '文章點贊量', PRIMARY KEY (`id`)) ;
3、采集隊列表CREATE TABLE `tmplist` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `content_url` varchar(255) DEFAULT NULL COMMENT '文章地址', `load` int(11) DEFAULT '0' COMMENT '讀取中標記', PRIMARY KEY (`id`), UNIQUE KEY `content_url` (`content_url`)) ;
以上就是由微信客戶端、微信號、anyproxy代理服務器、PHP程序、mysql數(shù)據(jù)庫共同組成的微信公眾號文章批量自動采集系統(tǒng)。關鍵詞:采集,系統(tǒng),文章,更新,公眾,持續(xù)