用无手机号怎么注册微信注册了微信•但忘记J密码怎么办

朝鲜严打民众用手机联系国外 违者将被逮捕_网易新闻
朝鲜严打民众用手机联系国外 违者将被逮捕
用微信扫码二维码
分享至好友和朋友圈
核心提示:10月起,朝鲜领导人金正恩发动打击与中国接壤地区民众非法使用手机行动。媒体称此举意在封锁朝鲜居民与国外的联系,将手机使用范围限制在国内,不允许用户拨打国际长途或连接国外的互联网。朝鲜当局一旦检测到非法信号将立即捉拿使用手机者。
朝鲜领导人金正恩发起了一场史无前例的多部门共同行动,下令严厉打击与中国接壤地区的居民非法使用手机,跟踪信号、派遣安全部队逮捕非法使用的用户。多部门联合打击此举意在封锁朝鲜居民与国外的联系,将手机使用范围限制在国内,不允许用户拨打国际长途或连接国外的互联网。在与中国接壤的地区,朝鲜居民用走私的手机连接中国的手机发射塔,从而进行外线呼叫。不过自今年10月份起,朝鲜当局收紧了对手机使用的限制,还利用无线电监测非法的手机信号。一名不愿透露姓名的消息人士称,一旦检测到非法信号,朝鲜当局将立即派出安全部队捉拿违法者。除了用无线电监测,朝鲜当局还向军方以及国家警察部门分派了特殊任务,参与打击行动。这名消息人士称:“他们甚至还调动了国家的平民防卫力量——工农赤卫队来参与这次活动。”朝鲜以前也发起过类似的打击非法使用手机的行动,但从未组织过像此次这样多部门的大规模行动。自上而下的指令来自与中国接壤的、北部边陲行政省两江道的消息人士称,这次收紧手机使用的指令由金正恩发出,他近日访问了国家安全部门及相关指挥机关后,发起了打击手机非法使用行为的活动。消息人士称:“金正恩命令私人、军事以及执法机构联合行动,没收每一部非法使用的手机。”在会见中,部分官员向金正恩汇报了此前粉碎手机非法使用行动,成功降低了朝鲜居民非法穿越边境河偷渡到中国的数量。来自咸镜北道的消息人士称,当局这种通过信号追踪抓捕非法使用手机的方式很难根除非法使用行为,因为边境地区的居民一般会深入到大山里去打电话。另外一名来自咸镜北道的消息人士称,当局无论采用多么严格的镇压措施总是有限度的,不可能根除人们非法使用手机。“你不可能整日盯着整个边境线,抓获每一个用户。”
手机信号覆盖五分之一消息人士称,非法流入朝鲜境内的中国手机已经超过了一百万,主要使用范围就是边境区,一些跨境贸易商需要手机在中国做生意。有的朝鲜居民还使用手机和他们在中国、韩国、日本等其他国家的亲友联系。朝鲜首次推手机服务的时间是2002年,初期仅限平壤,后来北火车站的爆炸事故禁止了两年服务。2008年,埃及电信公司orascom出人意料地在朝鲜设立子公司koryolink,推出首个也是唯一的3g业务,目前其手机信号已经覆盖了全国五分之一的领土。
本文来源:华龙网-重庆晨报
责任编辑:王晓易_NE0011
用微信扫码二维码
分享至好友和朋友圈
加载更多新闻
热门产品:   
:        
:         
热门影院:
阅读下一篇
用微信扫描二维码
分享至好友和朋友圈泛微移动信息门户 • 体验会盛大揭幕!
摘要:8月31日,泛微全国首场“移动门户·体验会”在上海盛大揭幕。近1000位来自各行各业的信息化同仁到场,聆听泛微全新移动门户解决方案,体验“将企业所有移动应用都装入一个手机APP”的酣畅感受。在移动互联兴盛的今天,“唯快不破”被奉为真谛。企业管理也是如此,网速的飞涨加上智能设备的普及,高效利用碎片时间的移动办公时代已然来临。然而,从PC到移动不是简单地应用平移,设备本身的差异、众多信息系统的融合、产业链条的整合、随需应变的能力等等,对移动办公解决方案提供商而言,都是全新的挑战。
今天,泛微整装出发,带着全新的移动门户前来,活动现场瞬间爆棚,原定500人的会议,最终被满满近千人撑满,由此可见企业对移动信息化的渴望与期待!
泛微客服总监隋清控场主持,张弛有度地引领,推动活动有序进行。
泛微客服总监 隋清
泛微上海大区总经理陈驰做开场辞,简介泛微十五年发展历程,感谢客户的一路陪伴,相约创造协同OA新未来。
泛微上海大区总经理 陈驰
| e-mobile,移动门户整体解决方案
泛微基于对协同OA的深刻理解以及与市场接触获得的实践经验,为了更好地满足市场需求,今天,基于泛微原生应用的e-mobile“移动门户”整体解决方案盛大发布。
泛微副总裁韦韶军现场倾情分享,从移动门户的整体架构,到移动门户的应用价值,实现统一组织、统一消息、统一应用、统一搜索、统一报表,并利用组织、集成、建模、内容、搜索、报表六大技术引擎平台完美支撑应用落地,最后给出一系列的移动门户最佳实践案例。全方位展示了“为何需要移动门户?移动门户的技术实现方式?移动门户的应用价值?”三大主题。
泛微副总裁 韦韶军
| 微信,另一种移动门户解决方案
微信作为一款革命性的社交工具,占据了中国90%的智能手机,亿万网民的生活已经与微信紧紧相连。那么,工作呢,是否也能借用微信这一大众熟悉的平台?泛微做到了。
泛微微信事业部总经理康渊炎到场分享微信办公解决方案。正所谓“他山之石可以攻玉”,把所有应用装入微信,同样可以实现六大统一。微信门户怎么创建?利用丰富的应用构建库、可定义的移动门户模版、可视化的移动门户管理、云桥微信集中件,只需要五步,企业定制化的微信移动办公平台就可呈现。
泛微微信集成事业部总经理 康渊炎
| 案例,走进移动门户的实践
移动门户解决方案是已经通过实践检验的成熟产品,活动现场特邀两大重量级客户亲临,用成功的实施案例验证移动协同、门户整合的巨大效能。
—SMG集团:安全、统一的移动办公门户
SMG是中国目前产业门类最多、产业规模最大的省级广电媒体及综合文化产业集团。携手泛微,构建了一体化OA平台,完成了13个职能部门、8个事业部和11个一级子公司内部OA建设和外部流程互联互通,解决了系统分散、协同效率低问题。更重要地,完成了安全、统一的移动办公门户搭建,并设有SMG自有应用商店,移动办公门户整合邮件、日历等应用,并实现了基于一定安全机制的公文移动审批。
SMG技术运营中心网络部主任 李泽强
— 上汽乘用车:以沟通为出发点构建移动门户
上汽集团乘用车公司作为全球八大汽车集团、世界500强企业上汽集团旗下整车厂,拥有荣威、名爵两大品牌。以行政沟通类服务为出发点,搭建移动化平台,逐步覆盖包括协同服务类,营销,产品设计等公司核心工作,形成统一的协同平台,实现向互联网+ 转型。
上汽集团乘用车协同服务平台架构师 王一峰
| 体验,酣畅移动办公
听完满是干货的分享,嘉宾们都已经跃跃欲试,纷纷来到了体验区。真实的demo场景,后台与前台匹配展现的H5动画,点一点,试一试,感受移动门户的包罗万象。
丰富的体验设备
开放的体验区
大会在宾客尽欢的愉悦氛围中圆满结束,技术方案的分享,真实场景的体验,希望到场的嘉宾都有收获,也再次感谢嘉宾的到场,感谢你们对泛微的信任。
微信搜索并关注科技讯公众账号:kejixun 更多精彩,早知道!
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点提示:用户名只能修改一次,请慎重选择名字,大讲堂建议用户使用真实姓名作为用户名。
微信红包系统设计 & 优化
&编者按:经过2014年一年的酝酿,2015微信红包总量创下历史新高,峰值1400万次/秒,8.1亿次每分钟,微信红包收发达10.1亿次,系统整体运行平稳, 在这里我分享下微信红包背后的技术。
讲师:jeri
核心功能&目标
首先,了解下微信红包的4个逻辑:摇/发/抢/拆。看似简单,实现可不简单再review下微信红包要实现目标:
摇:摇的流畅
快:抢的要快
爽:拆的爽
稳:能分享出去
系统难点:
1.中国运营商网络环境复杂,覆盖面广,春节期间网络吃紧,容易出现网络故障
2.在尖峰摇时如何避免服务雪崩
3.在服务资源有限时,如何提供柔性服务
4.如何构造有损服务
5.如何构造set模型
6.如何解决并发抢
7.如何实现实现数据一致性
系统整体架构图
跨区域网络解决方案
微信客户端分布全球,接入点较多,用户资料靠近接入点,可以加速用户资料访问,但是红包的业务逻辑层并不全网分布,业务逻辑层访问数据层比较多,数据层有状态强一致性问题,只能同用一个数据副本,比如上海用户与深圳用户在同个群里,抢同一个红包,如果订单数据在上海与深圳都有,在抢的时候,无法保证数据同步,可用性低,所以,设计系统时,一定要梳理清楚系统间的调用关系,优化接入层的业务逻辑,把网络耗时降到最小,系统吞吐量才能提升。
跨区域网络问题,在物理实施上,也需要有备份绕行的能力,这个可以在系统的底层框架中实现,当指定专线出现故障时,快速切换网络,恢复服务
如何构建有损服务
什么是有损服务?选择性牺牲一部分数据一致性和完整性从而保证核心功能绝大多数运行,经过一段时间窗口,数据一致性与完整性能得以恢复,这也是腾讯的一直运营策略,在有限资源前提下,量力而为,满足用户的核心需求
比如,春晚摇一摇,我们的核心点是摇/拆/分享,那系统的资源优先需要保证这些服务的响应,任何关联系统出现异常的时候马上进行系统降级,防止引起系统雪崩。
系统降级可以分为两个方面,一是把核心功能调用链路简化,减少依赖,通过辅助轻量化的服务实现,确保最短关键路径的可行,比方说在接入层置入摇红包逻辑,将每秒千万级请求转化为每秒万级的红包请求,再传到红包服务的后端逻辑,降低雪崩的可能性。
柔性服务.打造好的产品体验
柔性可用是在有损服务价值观支持下的方法,重点在于实际上会结合用户使用场景,根据资源消耗,调整产品策略,设计几个级别不同的用户体验场景,保证尽可能成功返回关键数据,并正常接受请求,绝不轻易倒下。
比如,红包的核心功能拆,拆完需要记录用户头像昵称,转帐资金划转,同时输出同个订单下其它拆记录,拆过程这些操作都可能失败,但是核心操作获取红包是成功的,此时,我们至少可以告诉用户抢到金额,不至于让用户焦急等待,不断重试,未完成的操作(头像补全与资金转帐),可以通异步补尝方式重试。这样解决了用户的问题,也缓解了系统压力。
如果构造set模型
Set模块就像一个集装箱,把各模块标准化,模块化,规模化,它为海量服务运营,特别是设备管理、网络架构,提供了宏观运营支撑框架,从而极大提高了海量服务运营效率。
微信红包的set模块,以拆服务为例,从接入层开始,数据开始sticky,按订单号路由,即按单号分set,同一个set尽可能在一个IDC 里,减少模块间调用的耗时,在同一个set内,逻辑层任何一台机器,调用方可实时摘除,如果是数据层发生故障,先在接入层,把新产生的红包订单号屏蔽有故障对应的set编号,比如,set1 数据库出现故障,为了避免在故障的set1 上继续产生新的支付请求,在订单生成器直接跳过set1的单号规则,把新请求导致其它set, 只有未抢完的部分红包,会提示故障,稍后恢复,阻止了故障引发的进一步恶化,在故障db上的数据,通过备机与业务逻辑层的数据核对,完成数据一致性的修复。
如何解决并发抢
群里红包的规则是金额随机抢,在一个大群发一个红包出去,抢并发请求量高,在同一个资源上操作,需要增加锁操作,避免一个抢总数超过发送红包总数,众所周所,mysql的加锁操作,很多抢在一个锁上等,性能损耗大,吞吐量下降,对于海量服务的操作,是不能满足要求。
在set模块的基础上,我们把发/抢的资源请求都会落到同一个资源set,在最外层,cache红包的状态,如果红包已经被抢完了,即刻返回,如果红包未接完,对于一个红包进去抢环节还有限流,这是第一级保护,通过一致性hash算法,一一个单到dao层都会路由到同一个机器的同一个进程,dao到mysql在现一个连接上完成抢操作,把并发抢修改成串行化,mysql可以无锁等待,性能明显提升。
如何实现数据一致性
谈到分布式系统,先回顾CAP理论
C:Consistency数据一致更新,所有变动都是同步的
A:高可用,好的响应性能
P: 分区容忍,可靠性
在我们的系统设计中,同样碰到这个问题,无法同时满足三个因子,移动互联网系统,高可用性是必要要求,数据分区也是分布式系统的条件,所以,我们设计系统时,只能尽量保证数据一致性,只要一定时间窗口内,完成数据一致,让用户满意。
微信红包的数据有几份,订单数据,用户数据,还有对应的cache数据,
N:数据副本份数红包有三份
R: 一次需读取的副本红包一次从一个副本可以全部读取需要数据
W: 一次写入数据2份实时写,一分异步化
R(1) + W(2) &=N从公式算出,我们的数据模型也是弱一致性
用户数据是异步更新,更新失败,通过消息中心,异步重试,根据DB资源负载设置调用方的调用阀值,除了实时重试,我们还有准实时数据核对,保证数据最终一致性。
请选择禁言时间:
Copyright (C) 1998 - 2013 Tencent. All Rights Reserved.&&腾讯公司 版权所有微信小程序功能及发展趋势_腾讯视频
三倍流畅播放
1080P蓝光画质
新剧提前看
1080P蓝光画质
纯净式无框播放器
三倍流畅播放
扫一扫 手机继续看
下载需先安装客户端
{clientText}
客户端特权:
3倍流畅播放
当前播放至 {time}
扫一扫 手机继续看
1.8万3700587736163.2万16.0万19.1万4.8万12.3万34153.4万9.0万116.3万2141387254850.5万4.4万8933.0万持续更新,微信公众号文章批量采集系统的构建=========日更新=========现在根据不同的微信个人号,会出现两种不同的历史消息页面地址,下面是另一种历史消息页的地址,第一种地址的链接会在anyproxy中显示302跳转: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=a226a081696afed0d9dfa6e5c78ad4e9a2b94aeaad6ac4dd87de3e56fe9cc2052f68aca6e99fd8e4c29abe4a049d1a71eeb2be5&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=2a0324183dbd55a2680d11ccbaa34cdb349ee9be58f5b666092ddb17adf8a88dccfd511c9e118aa324a38903f79cff940cf749ecd5a&devicetype=android-17&version=2605033c&lang=zh_CN&nettype=WIFI&a8scene=3&pass_ticket=Fo3zjtJcbPfijNHKUIQbV%2BeHsAqhbjJCwzTfV48u%2FCZRRGTmI8oqmHDxxfEL8ke%2B&wx_header=1
这个地址是通过微信客户端打开历史消息页面之后,再使用后面介绍的代理服务器软件获取到的。这里面有几个参数:action=;__biz=;uin=;key=;devicetype=;version=;lang=;nettype=;scene=;pass_ticket=;wx_header=;其中重要的参数是:__uin=;key=;pass_ticket=;这4个参数。__biz是公众号的一个类似id的参数,每个公众号拥有一个微信的biz,目前极小概率会发生公众号的biz会变化的事件;剩下的3个参数是有关用户的id和令牌票据之类的意思,这3个参数的值是通过微信的客户端生成后自动补充到地址栏中的。所以我们想采集公众号就必须通过一个微信客户端app。在以前的微信版本中这3个参数还可以获取一次之后在有效期之内多个公众号通用。现在的版本已经是每次访问一个公众号都会更换参数值。我现在所使用的方法只需要关注__biz这个参数就可以了。我的采集系统由以下几部分组成:1、一个微信客户端:可以是一台手机安装了微信的app,或者是用电脑中的安卓模拟器。经过实测ios的微信客户端在批量采集过程中崩溃率高于安卓系统。为了降低成本,我使用的是安卓模拟器。2、一个微信个人号:为了采集内容不仅需要微信客户端,还要有一个微信个人号专门用于采集,因为这个微信号就干不了其它事情了。3、本地代理服务器系统:目前使用的方法是通过Anyproxy代理服务器将公众号历史消息页面中的文章列表发送到自己的服务器上。具体安装设置方法在后面详细介绍。4、文章列表分析与入库系统:我用的是php语言编写的,后文将详细介绍如何分析文章列表和建立采集队列实现批量采集内容。步骤一、安装模拟器或使用手机安装微信客户端app,申请微信个人号并登录到app上面。这一点就不过多介绍了,大家都会。二、代理服务器系统安装目前我使用的是Anyproxy, 。这个软件的特点是可以获取到https链接的内容。在2016年年初的时候微信公众号和微信文章开始使用https链接。并且Anyproxy可以通过修改rule配置实现向公众号的页面中插入脚本代码。下面开始介绍安装与配置过程。1、安装 2、在命令行或者终端运行 npm install -g anyproxy,mac系统需要加上sudo;3、生成RootCA,https需要这个证书:运行命令sudo anyproxy --root(windows可能不需要sudo);4、启动anyproxy运行命令:sudo anyproxy -i;参数-i是解析HTTPS的意思;5、安装证书,在手机或安卓模拟器中安装证书:方法一: 启动anyproxy,浏览器打开
,能获取rootCA.crt文件方法二:启动anyproxy, 可以获取证书路径的二维码,移动端安装时会比较便捷建议通过二维码将证书安装到手机中。6、设置代理:安卓模拟器的代理服务器地址是wifi链接的网关,可以通过吧dhcp设置为静态后看到网关地址,看完后别忘了再设置为自动。手机中的代理服务器地址就是运行anyproxy的电脑的ip地址。代理服务器默认端口是8001;现在打开微信,点击到任意一个公众号历史消息或文章中,在终端都可以看到响应的代码滚动。如果没有出现,请检查手机的代理设置是否正确。现在打开浏览器地址 可以看到anyproxy的web界面。从微信中点开一个历史消息页面,然后再看浏览器的web界面,会滚动出现历史消息页面的地址。以/mp/getmasssendmsg开头的网址就是微信历史消息页面。左边一个小锁头表示这个页面是https加密的。现在我们点击一下这一行;=========日更新=========部分微信号以/mp/getmasssendmsg开头的网址会出现302跳转,跳转到了/mp/profile_ext?action=home开头的地址。所以点开这个地址才可以看到内容。右边如果出现了html的文件内容则表示解密成功。如果没有内容,请检查anyproxy的运行模式是否有参数i,是否生成了ca证书,手机是否正确安装证书。现在我们的手机中的所有内容都已经可以明文通过代理服务器了。下面我们要修改配置代理服务器,使公众号内容被获取到。一、找到配置文件:mac系统中配置文件的位置在/usr/local/lib/node_modules/anyproxy/lib/;windows系统请原谅我暂时不知道。应该可以根据类似mac的文件夹地址找到这个目录。二、修改文件rule_default.js找到replaceServerResDataAsync: function(req,res,serverResData,callback) 函数修改函数内容(请注意详细阅读注释,这里只是介绍原理,理解后根据自己的条件修改内容):=========日更新=========因为出现了两种页面形式,且在不同的微信号中始终显示同一种页面形式,但为了能兼容两种页面形式,以下的代码会保留两种页面形式的判断,你也可以根据自己的页面形式去掉lireplaceServerResDataAsync: function(req,res,serverResData,callback){
if(/mp\/getmasssendmsg/i.test(req.url)){//当链接地址为公众号历史消息页面时(第一种页面形式)
if(serverResData.toString() !== ""){
try {//防止报错退出程序
var reg = /msgList = (.*?);/;//定义历史消息正则匹配规则
var ret = reg.exec(serverResData.toString());//转换变量为string
HttpPost(ret[1],req.url,"getMsgJson.php");//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器
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格式的。
var json = JSON.parse(serverResData.toString());
if (json.general_msg_list != []) {
HttpPost(json.general_msg_list,req.url,"getMsgJson.php");//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器
}catch(e){
console.log(e);//错误捕捉
callback(serverResData);//直接返回第二页json内容
}else if(/mp\/profile_ext\?action=home/i.test(req.url)){//当链接地址为公众号历史消息页面时(第二种页面形式)
var reg = /var msgList = \'(.*?)\';/;//定义历史消息正则匹配规则(和第一种页面形式的正则不同)
var ret = reg.exec(serverResData.toString());//转换变量为string
HttpPost(ret[1],req.url,"getMsgJson.php");//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器
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)){//第二种页面表现形式的向下翻页后的json
var json = JSON.parse(serverResData.toString());
if (json.general_msg_list != []) {
HttpPost(json.general_msg_list,req.url,"getMsgJson.php");//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器
}catch(e){
console.log(e);
callback(serverResData);
}else if(/mp\/getappmsgext/i.test(req.url)){//当链接地址为公众号文章阅读量和点赞量时
HttpPost(serverResData,req.url,"getMsgExt.php");//函数是后文定义的,功能是将文章阅读量点赞量的json发送到服务器
}catch(e){
callback(serverResData);
}else if(/s\?__biz/i.test(req.url) || /mp\/rumor/i.test(req.url)){//当链接地址为公众号文章时(rumor这个地址是公众号文章被辟谣了)
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);
callback(serverResData);
上面这段代码是利用anyproxy可以修改返回页面内容的功能,向页面注入脚本,和将页面内容发送到服务器上。使用这个原理来批量采集公众号内容和阅读量。这段脚本中自定义了一个函数,下面详细介绍:在rule_default.js文件末尾添加以下代码:function HttpPost(str,url,path) {//将json发送到服务器,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://,这是服务器的域名。
path: path,//接收程序的路径和文件名
headers: {
'Content-Type': 'application/x-www-form- 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规则修改的主要部分,需要将json内容发送到自己的服务器,还要从服务器获取到下一页的跳转地址。这就涉及到了四个php文件:getMsgJson.php、getMsgExt.php、getWxHis.php、getWxPost.php在详细介绍这4个php文件之前,为了提高采集系统性能和降低崩溃率,我们还可以进行一些修改:安卓模拟器经常会访问一些的地址,这样会导致anyproxy死机,找到函数replaceRequestOption : function(req,option),修改函数内容:replaceRequestOption : function(req,option){
var newOption = option;
if(/google/i.test(newOption.headers.host)){
newOption.hostname = "www.baidu.com";
newOption.port
return newOption;
以上就是针对anyproxy的rule文件的修改配置,配置修改完成之后,重新启动anyproxy。mac系统里按control+c中断程序,再输入命令sudo anyproxy -i启动;如果启动报错,可能是程序没有退出干净,端口被占用。这时输入命令ps -a查看占用的pid,再输入命令“kill -9 pid”这里将pid替换成查询到的pid号码。杀死进程之后就可以启动anyproxy了。还是那句话windows的命令请原谅我不太熟悉。接下来详细介绍服务器上接收程序的设计原理:(以下代码并不是直接可以用的,只是介绍原理,其中一部分需要根据自己的服务器数据库框架进行编写)1、getMsgJson.php:这个程序负责接收历史消息的json并解析后存入数据库&?
$str = $_POST['str'];
$url = $_POST['url'];//先获取到两个POST变量
//先针对url参数进行操作
parse_str(parse_url(htmlspecialchars_decode(urldecode($url)),PHP_URL_QUERY ),$query);//解析url地址
$biz = $query['__biz'];//得到公众号的biz
//接下来进行以下操作
//从数据库中查询biz是否已经存在,如果不存在则插入,这代表着我们新添加了一个采集目标公众号。
//再解析str变量
$json = json_decode($str,true);//首先进行json_decode
if(!$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'];//图文消息发送时间
//在这里将图文消息链接地址插入到采集队列库中(队列库将在后文介绍,主要目的是建立一个批量采集队列,另一个程序将根据队列安排下一个采集的公众号或者文章内容)
//在这里根据$content_url从数据库中判断一下是否重复
if('数据库中不存在相同的$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;//标记一下是头条内容
//现在存入数据库
echo "头条标题:".$title.$lastId."\n";//这个echo可以显示在anyproxy的终端里
if($is_multi==1){//如果是多图文消息
foreach($v['app_msg_ext_info']['multi_app_msg_item_list'] as $kk=&$vv){//循环后面的图文消息
$content_url = str_replace("\\","",htmlspecialchars_decode($vv['content_url']));//图文消息链接地址
//这里再次根据$content_url判断一下数据库中是否重复以免出错
if('数据库中不存在相同的$content_url'){
//在这里将图文消息链接地址插入到采集队列库中(队列库将在后文介绍,主要目的是建立一个批量采集队列,另一个程序将根据队列安排下一个采集的公众号或者文章内容)
$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']));//封面图片
//现在存入数据库
echo "标题:".$title.$lastId."\n";
再次强调代码只是原理,其中一部分注视的代码要自己编写。2、getMsgExt.php获取文章阅读量和点赞量的程序&?
$str = $_POST['str'];
$url = $_POST['url'];//先获取到两个POST变量
//先针对url参数进行操作
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;
//根据biz和sn找到对应的文章
$read_num = $json['appmsgstat']['read_num'];//阅读量
$like_num = $json['appmsgstat']['like_num'];//点赞量
//在这里同样根据sn在采集队列表中删除对应的文章,代表这篇文章可以移出采集队列了
//$sql = "delete from `队列表` where `content_url` like '%".$sn."%'"
//然后将阅读量和点赞量更新到文章表中。
exit(json_encode($msg));//可以显示在anyproxy的终端里
3、getWxHis.php、getWxPost.php两个程序比较类似,一起介绍==========日更新==========因为出现了两种页面表现形式,拼接历史消息页面的地址也应该发生改变,但是目前实测,即使微信客户端出现的是第二种页面表现形式,也可以将第一种页面的链接地址发送给微信,同样有效。&?
//getWxHis.php 当前页面为公众号历史消息时,读取这个程序
//在采集队列表中有一个load字段,当值等于1时代表正在被读取
//首先删除采集队列表中load=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字段为当前时间戳。
//取得当前这一行的content_url字段
$url = $content_url;
//将load字段update为1
echo "&script&setTimeout(function(){window.location.href='".$url."';},2000);&/script&";//将下一个将要跳转的$url变成js脚本,由anyproxy注入到微信页面中。
//getWxPost.php 当前页面为公众号文章页面时,读取这个程序
//首先删除采集队列表中load=1的行
//然后从队列表中按照“order by id asc”选择多行(注意这一行和上面的程序不一样)
if(!empty('队列表') && count('队列表中的行数')&1){//(注意这一行和上面的程序不一样)
//取得第0行的content_url字段
$url = $content_url;
//将第0行的load字段update为1
//队列表还剩下最后一条时,就从存储公众号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拼接到地址中(注意:评论区有朋友以为key和pass_ticket也要拼接,实则不需要),通过js的方式输出到页面,如果下一条是文章,则将历史消息列表json中的文章地址直接输出为js。同样文章内容的地址中不包含uin和key这样的参数,这些参数都是由客户端自动补充的。这两个程序的微小差别是因为当读取公众号历史消息页面时,anyproxy会同时做两件事,第一是将历史消息的json发送到服务器,第二是获取到下一页的链接地址。但是这两个操作是存在时间差的,第一次读取下一页地址时候本来应该是得到当前这个公众号文章的第一条链接地址,但是这时候历史消息的json还没有发送到服务器,所以只能得到第二个公众号的历史消息页面。在读取第二个公众号历史消息页面之后得到的下一页地址则是第一个公众号的第一篇文章的地址。当队列还剩下一条记录时,就需要再去取得下一个公众号的链接地址,否则如果当队列空了再去取得下一个公众号的链接地址,就会循环到上面提到的第一次读取时的情况,这样就会出现两个公众号历史消息列表和文章采集穿插进行的情况。刚才这4个PHP程序提到了几个数据表,下面再讲一下数据表如何设计。这里只介绍一些主要字段,现实应用中还会根据自己程序的不同添加上其它有必要的字段。1、微信公众号表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 '文章编码,防止文章出现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数据库共同组成的微信公众号文章批量自动采集系统。在接下来的文章中,还会再进一步详细介绍如何保存文章内容,如何提高采集系统的稳定性,以及其它我的系统运行过程中得到的经验。非常希望大家能给予意见和交流,欢迎骚扰微信号cuijin。赞赏8 人赞赏170收藏分享举报文章被以下专栏收录{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\u002Fpay.zhihu.com\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[{&sourceColumn&:{&lastUpdated&:,&description&:&&,&permission&:&COLUMN_PUBLIC&,&memberId&:1375467,&contributePermission&:&COLUMN_PUBLIC&,&translatedCommentPermission&:&all&,&canManage&:true,&intro&:&&,&urlToken&:&c_&,&id&:24244,&imagePath&:&4b70deef7&,&slug&:&c_&,&applyReason&:&0&,&name&:&微信公众号内容的批量采集与应用&,&title&:&微信公众号内容的批量采集与应用&,&url&:&https:\u002F\u002Fzhuanlan.zhihu.com\u002Fc_&,&commentPermission&:&COLUMN_ALL_CAN_COMMENT&,&canPost&:true,&created&:,&state&:&COLUMN_NORMAL&,&followers&:1832,&avatar&:{&id&:&4b70deef7&,&template&:&https:\u002F\u002Fpic3.zhimg.com\u002F{id}_{size}.jpg&},&activateAuthorRequested&:false,&following&:false,&imageUrl&:&https:\u002F\u002Fpic3.zhimg.com\u002F4b70deef7_l.jpg&,&articlesCount&:4},&state&:&accepted&,&targetPost&:{&titleImage&:&&,&lastUpdated&:,&imagePath&:&&,&permission&:&ARTICLE_PUBLIC&,&topics&:[,9089],&summary&:&我从2014年就开始做微信公众号内容的批量采集,最开始的目的是为了做一个html5的垃圾内容网站。当时垃圾站采集到的微信公众号的内容很容易在公众号里面传播。当时批量采集特别好做,采集入口是公众号的历史消息页。这个入口到现在也是一样,只不过越来越难…&,&copyPermission&:&ARTICLE_COPYABLE&,&translatedCommentPermission&:&followee&,&likes&:0,&origAuthorId&:0,&publishedTime&:&T07:05:01+08:00&,&sourceUrl&:&&,&urlToken&:,&id&:1907333,&withContent&:false,&slug&:,&bigTitleImage&:false,&title&:&持续更新,微信公众号文章批量采集系统的构建&,&url&:&\u002Fp\u002F&,&commentPermission&:&ARTICLE_FOLLOWEE_CAN_COMMENT&,&snapshotUrl&:&&,&created&:,&comments&:0,&columnId&:0,&content&:&&,&parentId&:0,&state&:&ARTICLE_PUBLISHED&,&imageUrl&:&&,&author&:{&bio&:&中华人民共和国宪法第三十五条:中华人民共和国公民有言论、出版、集会、结社、游行、示威的自由&,&isFollowing&:false,&hash&:&b6d9d239fb&,&uid&:68,&isOrg&:false,&slug&:&fankouzu&,&isFollowed&:false,&description&:&&,&name&:&飯口組組長&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Ffankouzu&,&avatar&:{&id&:&30f0ae3f8&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&memberId&:1375467,&excerptTitle&:&&,&voteType&:&ARTICLE_VOTE_CLEAR&},&id&:495182}],&title&:&持续更新,微信公众号文章批量采集系统的构建&,&author&:&fankouzu&,&content&:&我从2014年就开始做微信公众号内容的批量采集,最开始的目的是为了做一个html5的垃圾内容网站。当时垃圾站采集到的微信公众号的内容很容易在公众号里面传播。当时批量采集特别好做,采集入口是公众号的历史消息页。这个入口到现在也是一样,只不过越来越难采集了。采集的方式也更新换代了好多个版本。后来在2015年html5垃圾站不做了,转向将采集目标定位在本地新闻资讯类公众号,前端显示做成了app。所以就形成了一个可以自动采集公众号内容的新闻app。曾经我一直担心有一天微信技术升级之后无法采集内容了,我的新闻app就失效了。但随着微信不断的技术升级,采集方法也随之升级,反而使我越来越有信心。只要公众号历史消息页存在,就能批量采集到内容。所以今天决定将采集方法整理之后写下来。我的方法来源于许多同行的分享精神,所以我也会延续这个精神,将我的成果分享出来。\u003Cp\u003E\u003Cb\u003E本篇文章将持续更新,你所看到的内容将保证在看到的时间是可用的。\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E首先我们来看一个微信公众号历史消息页面的链接地址:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Ehttp:\u002F\u002Fmp.weixin.qq.com\u002Fmp\u002Fgetmasssendmsg?__biz=MjM5MzczNjY2NA==#wechat_webview_type=1&wechat_redirect\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E=========日更新=========\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E现在根据不同的微信个人号,会出现两种不同的历史消息页面地址,下面是另一种历史消息页的地址,第一种地址的链接会在anyproxy中显示302跳转:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Ehttps:\u002F\u002Fmp.weixin.qq.com\u002Fmp\u002Fprofile_ext?action=home&__biz=MzA3NDk5MjYzNg==&scene=124#wechat_redirect\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cbr\u003E\u003Cp\u003E第一种链接地址的页面样式:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-f63c8dcbab824_b.jpg\& data-rawwidth=\&750\& data-rawheight=\&1334\& class=\&origin_image zh-lightbox-thumb\& width=\&750\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-f63c8dcbab824_r.jpg\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='750'%20height='1334'&&\u002Fsvg&\& data-rawwidth=\&750\& data-rawheight=\&1334\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&750\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-f63c8dcbab824_r.jpg\& data-actualsrc=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-f63c8dcbab824_b.jpg\&\u003E\u003C\u002Ffigure\u003E第二种链接地址的页面样式:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-a14983b45aad17a068dc636b3556f99f_b.jpg\& data-rawwidth=\&640\& data-rawheight=\&1136\& class=\&origin_image zh-lightbox-thumb\& width=\&640\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-a14983b45aad17a068dc636b3556f99f_r.jpg\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='640'%20height='1136'&&\u002Fsvg&\& data-rawwidth=\&640\& data-rawheight=\&1136\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&640\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-a14983b45aad17a068dc636b3556f99f_r.jpg\& data-actualsrc=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-a14983b45aad17a068dc636b3556f99f_b.jpg\&\u003E\u003C\u002Ffigure\u003E根据目前掌握的信息,两种页面形式无规律的出现在不同的微信号中,有的微信号始终是第一种页面形式,有的就始终是第二种页面形式。\u003C\u002Fp\u003E\u003Cp\u003E上面这个链接是一个微信公众号历史消息页面的真实链接,但是我们把这个链接输入到浏览器中会显示:请从微信客户端访问。这是因为实际上这个链接地址还需要几个参数才能正常显示内容。下面我们就来看看可以正常显示内容的完整链接是什么样的:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F第一种链接\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Ehttp\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002Fmp.weixin.qq.com\u002Fmp\u002Fgetmasssendmsg?__biz=MjM5NTM1NjczMw==&uin=NzM4MTk1ODgx&key=a226a081696afed0d9dfa6e5c78ad4e9a2b94aeaad6ac4dd87de3e56fe9cc2052f68aca6e99fd8e4c29abe4a049d1a71eeb2be5&devicetype=android-17&version=2605033c&lang=zh_CN&nettype=WIFI&ascene=1&pass_ticket=zbA7PswOPKySRpyEYI5kDCjRiljxcpzdbTuVMauFGemgdp8R1DY1uQY49srehWab&wx_header=1\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F第二种\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Ehttp\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002Fmp.weixin.qq.com\u002Fmp\u002Fprofile_ext?action=home&__biz=MzA3NDk5MjYzNg==&scene=124&uin=NzM4MTk1ODgx&key=2a0324183dbd55a2680d11ccbaa34cdb349ee9be58f5b666092ddb17adf8a88dccfd511c9e118aa324a38903f79cff940cf749ecd5a&devicetype=android-17&version=2605033c&lang=zh_CN&nettype=WIFI&a8scene=3&pass_ticket=Fo3zjtJcbPfijNHKUIQbV%2BeHsAqhbjJCwzTfV48u%2FCZRRGTmI8oqmHDxxfEL8ke%2B&wx_header=1\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E\u003Cb\u003E这个地址是通过微信客户端打开历史消息页面之后,再使用后面介绍的代理服务器软件获取到的。\u003C\u002Fb\u003E这里面有几个参数:\u003C\u002Fp\u003E\u003Cp\u003Eaction=;__biz=;uin=;key=;devicetype=;version=;lang=;nettype=;scene=;pass_ticket=;wx_header=;\u003C\u002Fp\u003E\u003Cp\u003E其中重要的参数是:__uin=;key=;pass_ticket=;这4个参数。\u003C\u002Fp\u003E\u003Cp\u003E__biz是公众号的一个类似id的参数,每个公众号拥有一个微信的biz,目前极小概率会发生公众号的biz会变化的事件;\u003C\u002Fp\u003E\u003Cp\u003E剩下的3个参数是有关用户的id和令牌票据之类的意思,\u003Cb\u003E这3个参数的值是通过微信的客户端生成后自动补充到地址栏中的。\u003C\u002Fb\u003E所以我们想采集公众号就必须通过一个微信客户端app。在以前的微信版本中这3个参数还可以获取一次之后在有效期之内多个公众号通用。现在的版本已经是每次访问一个公众号都会更换参数值。\u003C\u002Fp\u003E\u003Cp\u003E我现在所使用的方法只需要关注__biz这个参数就可以了。\u003C\u002Fp\u003E\u003Cbr\u003E我的采集系统由以下几部分组成:\u003Cp\u003E1、一个微信客户端:可以是一台手机安装了微信的app,或者是用电脑中的安卓模拟器。经过实测ios的微信客户端在批量采集过程中崩溃率高于安卓系统。为了降低成本,我使用的是安卓模拟器。\u003C\u002Fp\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-414d43c63db7b1d52c74c64b31282fe7_b.jpg\& data-rawwidth=\&431\& data-rawheight=\&653\& class=\&origin_image zh-lightbox-thumb\& width=\&431\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-414d43c63db7b1d52c74c64b31282fe7_r.jpg\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='431'%20height='653'&&\u002Fsvg&\& data-rawwidth=\&431\& data-rawheight=\&653\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&431\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-414d43c63db7b1d52c74c64b31282fe7_r.jpg\& data-actualsrc=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-414d43c63db7b1d52c74c64b31282fe7_b.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cbr\u003E\u003Cp\u003E2、一个微信个人号:为了采集内容不仅需要微信客户端,还要有一个微信个人号专门用于采集,因为这个微信号就干不了其它事情了。\u003C\u002Fp\u003E\u003Cp\u003E3、本地代理服务器系统:目前使用的方法是通过Anyproxy代理服务器将公众号历史消息页面中的文章列表发送到自己的服务器上。具体安装设置方法在后面详细介绍。\u003C\u002Fp\u003E\u003Cp\u003E4、文章列表分析与入库系统:我用的是php语言编写的,后文将详细介绍如何分析文章列表和建立采集队列实现批量采集内容。\u003C\u002Fp\u003E\u003Cp\u003E步骤\u003C\u002Fp\u003E\u003Cp\u003E一、安装模拟器或使用手机安装微信客户端app,申请微信个人号并登录到app上面。这一点就不过多介绍了,大家都会。\u003C\u002Fp\u003E\u003Cp\u003E二、代理服务器系统安装\u003C\u002Fp\u003E\u003Cp\u003E目前我使用的是Anyproxy,\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fanyproxy.io\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EAnyProxy\u003C\u002Fa\u003E 。这个软件的特点是可以获取到https链接的内容。在2016年年初的时候微信公众号和微信文章开始使用https链接。并且Anyproxy可以通过修改rule配置实现向公众号的页面中插入脚本代码。下面开始介绍安装与配置过程。\u003C\u002Fp\u003E\u003Cp\u003E1、安装 \u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fnodejs.org\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ENodeJS\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E2、在命令行或者终端运行 npm install -g anyproxy,mac系统需要加上sudo;\u003C\u002Fp\u003E\u003Cp\u003E3、生成RootCA,https需要这个证书:运行命令sudo anyproxy --root(windows可能不需要sudo);\u003C\u002Fp\u003E\u003Cp\u003E4、启动anyproxy运行命令:sudo anyproxy -i;参数-i是解析HTTPS的意思;\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E5、安装证书,在手机或安卓模拟器中安装证书:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E方法一: 启动anyproxy,浏览器打开 \u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Flocalhost%3AFfetchCrtFile\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Elocalhost:FfetchCrt\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003EFile\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E ,能获取rootCA.crt文件\u003Cbr\u003E\u003C\u002Fli\u003E\u003Cli\u003E方法二:启动anyproxy,\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Flocalhost%3AFqr_root\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Elocalhost:Fqr_root\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E 可以获取证书路径的二维码,移动端安装时会比较便捷\u003Cbr\u003E\u003C\u002Fli\u003E\u003Cli\u003E建议通过二维码将证书安装到手机中。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E6、设置代理:安卓模拟器的代理服务器地址是wifi链接的网关,可以通过吧dhcp设置为静态后看到网关地址,看完后别忘了再设置为自动。手机中的代理服务器地址就是运行anyproxy的电脑的ip地址。代理服务器默认端口是8001;\u003C\u002Fp\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-f8d269f0567efeee6b1f83_b.jpg\& data-rawwidth=\&431\& data-rawheight=\&653\& class=\&origin_image zh-lightbox-thumb\& width=\&431\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-f8d269f0567efeee6b1f83_r.jpg\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='431'%20height='653'&&\u002Fsvg&\& data-rawwidth=\&431\& data-rawheight=\&653\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&431\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-f8d269f0567efeee6b1f83_r.jpg\& data-actualsrc=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-f8d269f0567efeee6b1f83_b.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cp\u003E现在打开微信,点击到任意一个公众号历史消息或文章中,在终端都可以看到响应的代码滚动。如果没有出现,请检查手机的代理设置是否正确。\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-ddc05be32f5dc14dbc827_b.jpg\& data-rawwidth=\&1193\& data-rawheight=\&604\& class=\&origin_image zh-lightbox-thumb\& width=\&1193\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-ddc05be32f5dc14dbc827_r.jpg\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='1193'%20height='604'&&\u002Fsvg&\& data-rawwidth=\&1193\& data-rawheight=\&604\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&1193\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-ddc05be32f5dc14dbc827_r.jpg\& data-actualsrc=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-ddc05be32f5dc14dbc827_b.jpg\&\u003E\u003C\u002Ffigure\u003E\u003C\u002Fp\u003E\u003Cp\u003E现在打开浏览器地址\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Flocalhost%3A8002\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Elocalhost:C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E 可以看到anyproxy的web界面。从微信中点开一个历史消息页面,然后再看浏览器的web界面,会滚动出现历史消息页面的地址。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-45bcbcfad12d8_b.jpg\& data-rawwidth=\&1165\& data-rawheight=\&686\& class=\&origin_image zh-lightbox-thumb\& width=\&1165\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-45bcbcfad12d8_r.jpg\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='1165'%20height='686'&&\u002Fsvg&\& data-rawwidth=\&1165\& data-rawheight=\&686\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&1165\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-45bcbcfad12d8_r.jpg\& data-actualsrc=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-45bcbcfad12d8_b.jpg\&\u003E\u003C\u002Ffigure\u003E以\u002Fmp\u002Fgetmasssendmsg开头的网址就是微信历史消息页面。左边一个小锁头表示这个页面是https加密的。现在我们点击一下这一行;\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E=========日更新=========\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E部分微信号以\u002Fmp\u002Fgetmasssendmsg开头的网址会出现302跳转,跳转到了\u002Fmp\u002Fprofile_ext?action=home开头的地址。所以点开这个地址才可以看到内容。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-290cede650af43ba98f6f2f5ae81d06b_b.jpg\& data-rawwidth=\&1165\& data-rawheight=\&686\& class=\&origin_image zh-lightbox-thumb\& width=\&1165\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-290cede650af43ba98f6f2f5ae81d06b_r.jpg\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='1165'%20height='686'&&\u002Fsvg&\& data-rawwidth=\&1165\& data-rawheight=\&686\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&1165\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-290cede650af43ba98f6f2f5ae81d06b_r.jpg\& data-actualsrc=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-290cede650af43ba98f6f2f5ae81d06b_b.jpg\&\u003E\u003C\u002Ffigure\u003E右边如果出现了html的文件内容则表示解密成功。如果没有内容,请检查anyproxy的运行模式是否有参数i,是否生成了ca证书,手机是否正确安装证书。\u003C\u002Fp\u003E\u003Cp\u003E现在我们的手机中的所有内容都已经可以明文通过代理服务器了。下面我们要修改配置代理服务器,使公众号内容被获取到。\u003C\u002Fp\u003E\u003Cp\u003E一、找到配置文件:\u003C\u002Fp\u003E\u003Cp\u003Emac系统中配置文件的位置在\u002Fusr\u002Flocal\u002Flib\u002Fnode_modules\u002Fanyproxy\u002Flib\u002F;windows系统请原谅我暂时不知道。应该可以根据类似mac的文件夹地址找到这个目录。\u003C\u002Fp\u003E\u003Cp\u003E二、修改文件rule_default.js\u003C\u002Fp\u003E\u003Cp\u003E找到replaceServerResDataAsync: function(req,res,serverResData,callback) 函数\u003C\u002Fp\u003E\u003Cp\u003E修改函数内容(请注意详细阅读注释,这里只是介绍原理,理解后根据自己的条件修改内容):\u003C\u002Fp\u003E\u003Cp\u003E=========日更新=========\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E因为出现了两种页面形式,且在不同的微信号中始终显示同一种页面形式,但为了能兼容两种页面形式,以下的代码会保留两种页面形式的判断,你也可以根据自己的页面形式去掉li\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EreplaceServerResDataAsync\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ereq\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eres\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EserverResData\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ecallback\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&sr\&\u003E\u002Fmp\\\u002Fgetmasssendmsg\u002Fi\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Etest\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ereq\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)){\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F当链接地址为公众号历史消息页面时(第一种页面形式)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EserverResData\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EtoString\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E!==\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Etry\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F防止报错退出程序\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ereg\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&sr\&\u003E\u002FmsgList = (.*?);\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F定义历史消息正则匹配规则\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eret\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ereg\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eexec\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EserverResData\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EtoString\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E());\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F转换变量为string\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003EHttpPost\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eret\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&mi\&\u003E1\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E],\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ereq\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&getMsgJson.php\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ehttp\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'http'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ehttp\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eget\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'http:\u002F\u002Fxxx.com\u002FgetWxHis.php'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eres\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F这个地址是自己服务器上的一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxHis.php的原理。\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Eres\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eon\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'data'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Echunk\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecallback\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Echunk\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E+\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EserverResData\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F将返回的代码插入到历史消息页面中,并返回显示出来\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E})\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E});\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Ecatch\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ee\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F如果上面的正则没有匹配到,那么这个页面内容可能是公众号历史消息页面向下翻动的第二页,因为历史消息第一页是html格式的,第二页就是json格式的。\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Etry\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ejson\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EJSON\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eparse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EserverResData\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EtoString\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E());\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ejson\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Egeneral_msg_list\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E!=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[])\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003EHttpPost\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ejson\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Egeneral_msg_list\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ereq\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&getMsgJson.php\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Ecatch\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ee\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Econsole\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elog\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ee\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F错误捕捉\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecallback\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EserverResData\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F直接返回第二页json内容\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Eelse\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&sr\&\u003E\u002Fmp\\\u002Fprofile_ext\\?action=home\u002Fi\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Etest\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ereq\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)){\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F当链接地址为公众号历史消息页面时(第二种页面形式)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Etry\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ereg\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&sr\&\u003E\u002Fvar msgList = \\'(.*?)\\';\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F定义历史消息正则匹配规则(和第一种页面形式的正则不同)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eret\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ereg\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eexec\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EserverResData\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EtoString\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E());\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F转换变量为string\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003EHttpPost\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eret\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&mi\&\u003E1\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E],\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ereq\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&getMsgJson.php\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ehttp\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'http'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ehttp\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eget\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'http:\u002F\u002Fxxx.com\u002FgetWxHis'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eres\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F这个地址是自己服务器上的一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxHis.php的原理。\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Eres\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eon\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s1\&\u003E'data'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Echunk\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecallback\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Echunk\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E+\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EserverResData\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F将返回的代码插入到历史消息页面中,并返回显示出来\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E})\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E});\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Ecatch\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ee\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecallback\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EserverResData\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Eelse\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&sr\&\u003E\u002Fmp\\\u002Fprofile_ext\\?action=getmsg\u002Fi\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Etest\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ereq\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eurl\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)){\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F第二种页面表现形式的向下翻页后的json\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Etry\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ejson\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EJSON\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eparse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EserverResData\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EtoString\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E());\u003C\u002Fspan\u003E\n
\u003Cspan class=}

我要回帖

更多关于 虚拟手机号注册微信 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信