前端妹子跟我抱怨她们的减少页面加载时间方法很慢的时候,如何在她

1.9K89 条评论分享收藏感谢收起赞同 7813 条评论分享收藏感谢收起前端妹子跟我抱怨她们的页面加载很慢的时候,如何在她面前优雅地装逼?-土地公问答
前端妹子跟我抱怨她们的页面加载很慢的时候,如何在她面前优雅地装逼?
前端妹子跟我抱怨她们的页面加载很慢的时候,如何在她面前优雅地装逼?
我是个后端RD,看上了一个前端妹子,昨天吃饭的时候她跟我抱怨她们的页面打开很慢,如何才能快速的分析页面加载慢的原因,在妹子面前表现一下呢?
看来题主你的目的是装逼,优雅地装逼,要让妹子觉得你很牛逼对不对?要让妹子听你分析完之后就投怀送抱对不对?首先,想装逼就要显得随性、自然,看一眼就知道问题在哪。如果你需要吭吭哧哧的查半天log、分析core文件,那逼格自然就降低了许多。那如何才能随性自然呢?答案是看网页瀑布图。啥是瀑布图?这都不知道还追前端妹子?用chrome打开网页,按住option+command+i(windows是F12,但是如果你按的是这个,那么你怎么敢说你要装逼,前端团队都是清一水的mac啊亲,先换个mac再装逼),打开开发者工具看network。有了瀑布图,下面才是装逼的重点,要故作轻松、轻描淡写的扫一眼瀑布图,然后沉思几秒,语调略带深沉的跟妹子说:“我知道了”。当然,你要真的知道才行,不给妹子说出个所以然来,最后死的还是你。造成加载很慢的原因很多,但是你只需要知道一些就可以了,下面我就给你说一些常见的问题以及识别方法,如果这些情况都不是,那就只能祝你好运了哥们。1、你们后端的问题看到没,第一个请求特别长、特别长,明显比其他请求放到一起不和谐。一般网页第一个请求是动态请求的概率比较大,如果这个请求特别耗时,那肯定不是前端的责任,不是妹子的问题,伦家的html都没加载完呢,你怎么就能说是前端的问题呢。作为一个后端RD,你应该有这种觉悟,勇敢的说这是你的责任,表现出一个男人的气魄来,让妹子觉得你是一个负责的好男人。优化php、优化数据库、优化一切可以优化的东西,要让妹子觉得很爽才行。2、请求数太多数一下瀑布图总共有多少行,onload之前如果有几百行,那么请求就太多了。问一下妹子,一下子加载那么多资源真的好么?跟妹子说,css,js该合并的合并,图标该精灵的精灵,告诉妹子使用字体图标也能提升你高大上的形象。还有,有些不重要的东西不用放到onload之前加载,放到后面也一样嘛。网页发请求数就跟妹子的前男友数一样,越少越好。3、老鼠屎看到图中的这个请求没?再看看其他请求,这个请求比其他请求的时间大出一个数量级。这种情况一般是因为某一个资源太慢了,它就是一颗老鼠屎,坏掉了整锅汤,导致网页整体变慢。资源慢的原因,你可以跟妹子去星巴克,两个人采取结对编程的方式慢慢把玩这颗老鼠屎,概率比较大的几个可能是:a)资源在第三方站点上,他们很慢;b)这个资源太大了;c)这个资源使用的域名有问题。4、网络问题仔细看一下一个单独的http请求,他们会分为好几段,分别是域名解析、建立连接、发送请求、等待响应和接收数据几个阶段。理论上域名解析和建立连接应该占用的时间很小才对,主要的时间应该用在后面几个阶段上。上图中,浅灰色和灰色分别代表域名解析和建立连接,可以看出这两个请求中花费在网络层上的时间太长了,超过总时间的一半还要多。网络层时间过长除了可能和底层网络有关之外,还可能和站点的服务端性能有关(后端RD的事情哦)。当然,如果这种情况发生在向第三方站点发送的请求上(实际上也经常发生),你就可以建议妹子取消或者更换某些站点功能从而避免这样的请求了。5、接收数据时间过长上面说了,http请求的大部分时间应该花在后面几个阶段,比如等待响应和接收数据。但是,如果接收数据的时间太长了,长到数百毫秒甚至以秒计算的时候,那也是有问题的。这种情况一般是因为下载的内容太重了,例如大图片、大脚本等。这类问题可以使用GZIP压缩、图片压缩或者JS/CSS的minify等手段来解决。6、js阻塞请求图中两个连续的请求之间出现了一个很大的空隙,为啥会出现这个空隙呢?可能是因为妹子写的js性能有问题,解析执行js花了很长时间,导致这段时间的资源加载都被阻塞住了。如果发生了这个情况,你就应该耐心安慰妹子,问一下妹子是不是在写代码的时候身体不舒服啊、心情不好啊之类的关心一下,切记不能直接说妹子代码写的不行,不然肯定没有然后。7、如果以上都没有可以和妹子一一翻看每个http请求,仔细研究每个请求头响应头,看看是不是没有设置缓存啦,图片优化的不够好啦之类的。如果担心自己分析不好,可以先找个工具分析一下,比如:把上面这张图拿给妹子看看,问题一目了然。写到这里我忽然想到了一点,妹子抱怨慢的时候你当时没有装逼,现在才学如何装逼,还来得及么?来得及么?得及么?及么?么?-------------------------------------------分割线----------------------------------------------看到评论里很多说答主注定孤独一生,本来想回复「已结婚」,结果旁边的后端RD马上回了句「接盘侠」本来想回复「已当爹」,结果旁边的后端RD马上回了句「喜当爹」
蠢货~为什么要装逼.妹子抱怨了,你就去妹子那边看一下.手把手看一看,然后能解决也别解决,然后聊聊天,扯扯蛋.然后回去再去解决这个问题.如果不懂这个,再来问为什么慢,第二天再过去修复.不管是不是麻烦,一定要装出这个问题很麻烦的样子,然后解决掉.妹子很感谢的样子,然后叫妹子请客吃饭吧.妹子这种时候,不请的话,那你就反请妹子,然后带走.妈的我这种机智的小贱人怎么没有女朋友~~~~~
看完各位的答案,知道为什么你们没有妹子了?题主你要的是妹子对你的好感,不是搞技术啊!不是装逼啊!没有妹子的原因就在于你们总是且精通于去解决问题。你们精通的是男性语言。根本就不知道女性语言!而且试图用男性语言去解决女性语言的问题。这不是坑爹么?男人对他人抱怨的时候,多半是在寻求帮助,这个不用我解释,各位都懂。但是!但是!那个可是妹子啊!妹子在跟你抱怨的时候根本不是在寻求帮助!而是在表达情绪。so,你就尽情装B吧。怎么装都不会有结果的。人家的需求是希望得到共鸣或者安慰或者其他情感上的交流,不是解决问题,甚至人家根本不在意这么零点几秒的打开时间!需求不明确,如何开发?手机打字,大拇指不是一般累啊!
看到第一个答案这么认真,我不禁为题主的感情生活担心。不要分析,是的,不要分析,你做的再好也是煞风景。请她出去散散心,吹吹风,吃吃烛光晚餐然后回来跟领导汇报一下,上个cdn,服务器升升级。
使用页面缓存技术。
偷偷给她设置一个代理,到自己的机器上,然后时不时的阻塞一下她的请求,让她能经常来问你。而且还能看看请求内容,知道妹子的喜好。。。
F12看看network 看看timeline。。。然后就没有然后了
其实这个问题,归根结底还是要解决程序员如何找女朋友的问题上来。程序员为什么没有女朋友?有的女人就像Windows 虽然很优秀,但是安全隐患太大。 有的女人就像UNIX 她条件很好,然而不是谁都能玩的起。 有的女人就像C# 长的很漂亮,但是家务活不行。 有的女人就像C++,她会默默的为你做很多的事情。 有的女人就像JAVA,只需一点付出她就会为你到处服务。 有的女人就像JAVA script,虽然对她处处小心但最终还是没有结果。 有的女人就像汇编 虽然很麻烦,但是有的时候还得求它。 有的女人就像 SQL,她会为你的发展带来莫大的帮助。 爱情就是死循环,一旦执行就陷进去了。 爱上一个人,就是内存泄露,你永远释放不了。 真正爱上一个人的时候,那就是常量限定,永远不会改变。 女朋友就是私有变量,只有我这个类才能调用。 情人就是指针,用的时候一定要注意,要不然就带来巨大的灾难。 我在今年的暑假重新认识了你。从毫不设防到退回壕沟,躲着。你有的时候像windows,你的好,已经给了谁,我知道你的指针指向的是07年的那个他;你有的时候像JAVA script,我的小心已经凋谢在你的漠然的目光下。你把我推进了死循环,然后转身离去,我被转晕,看不清你的背影。给自己限定一个常量似乎很傻,常量没有牵挂,可是设定常量的人有,他在设定之前忘掉了开销,永远。于是你成为了UNIX,我微笑退后,慢慢走远。在我强颜欢笑的时候,我遇到了和你的好姐妹,一个失去了指针的C++。她自然而然地对我好,我被自己的感动刺痛。她楞楞的没有发现,我默默地收回自己的指针,我知道没有丘比特的弓,我做不到。如果有一天我指向她,所有你身边的人都会报错,包括她。还有7个月,你们会去这个星球的那一面,一个和我有120度地心夹角的地方。我知道不可能所以我学会了无动于衷。因为一场暧昧,一场空我的错。呵呵如果让我早点知道,我不会傻傻的在原地转三个圈。突然想到事不过三,释然了。为什么C++课本上没有告诉我,我是一个没有私有变量的类。男程序员如何找女朋友?首先,让自己变的优秀。这个不是说技术层面,主要是想说一个木桶原理。出去工作做的专业以外,生活方面才是根本。比如衣着,个人卫生,内在辞藻修养。让人一眼看不出你的邋遢,这个不是一套衣服就能解决的,这个需要花一些时间去细心打理、培养的一个习惯。很多人没有对象,其实只是自身的性格等原因,跟周围环境少只有一点点关系。如果自己没有意识到,不去改善的话,那即使碰到了喜欢的女孩,也是很难追到手的。其次,发现机会,拓宽渠道。网上相亲平台很多,选择一两个可靠,比较信赖的去参加,多接触人。另外,不要抱坏心思,那样得不偿失,一旦习惯了以后还不容易改回来。最后,一定要把握住机会,珍惜自己与别人的时间。
慢么?没有啊!是你的电脑有毛病吧?你重装下电脑试试!
妹子已经跟你讨论这个问题了,你再怎么装逼都没用了。
掐指一算最优雅了
我说就不能简单地用 Httpwatch、Firebug 之类的查一下么……优雅有什么用啊……
废话少说,上图
你电脑太慢了,晚上我去你家给你装系统…
只想告诉你办公室恋情没有好结果,部门恋情没有好结果,公司恋情没有好结果。好自为之吧。
前端妹子、后端妹子、上端妹子以及下端妹子,她们四个只在意结果,你整太多过程她们就会跟着给她们结果的汉子跑了。
题主问问题真机智,如果您直接问:页面加载慢,如何优化,这个问题会鲜有回答。但是问如何帮助前端妹子优化加载慢的页面,会有不少回答,哈哈哈
后端还是去捡肥皂吧……
认真听完,全程直视妹子的眼睛,尽量做到目光深邃,有眼镜就推一下眼镜,高冷学霸气质端起来,“待会我帮你看看。”……然后技术的东西你们随意……据我所知,大多数妹子萌(颜好)沉默寡言技术宅,话太多有卖弄嫌疑,嗯。
有时候真搞不懂你们这些搞IT的,妹子真的关心你技术牛不牛吗?你不风俗幽默,不温柔体贴,不身强体壮,光技术好有毛用?充其量也就让她崇拜你吧
其它类似问题
其它人正在问的问题&b&1. 模块定义方式&/b&&br&Javascript 的经典模块定义方式是三种:AMD,CMD 和 UMD&br&&br&AMD 是异步加载模块,天然合适前端。&br&CMD 是一般加载模块,天然合适后端。&br&UMD 是通用加载模块,天然前后端都可以使用。&br&&br&然而现在加载方式,前后端都可以实现加载以上任何一种定义,而写法更偏向写UMD(如果是全端模块的话)&br&&br&所以要写模块,第一就是选择模块定义。推荐UMD&br&&br&&b&2.DI,依赖注入&/b&&br&依赖注入的前提是之一模块化,但还有一条就是接口相同。(JS在接口定义方面比较弱,都是手动控制的。),然后就是两个接口相同的模块进行替换,程序可以正常编译运行。&br&&br&这个经常是用于测试,以及替换第三方服务时候使用。&br&&br&&b&3.中间件&/b&&br&这条就是回答这个问题的核心了。&br&&br&中间件一般称为middleware,不过我这里更多的意思是wrapper,也就是API再次分装了。&br&&br&这里有个原则,凡是第三方插件或者第三方服务,都必须使用中间件重新封装API一次,才能在自己的主程序中使用。而你的主程序,之后能使用中间件的API。&br&&br&另外中间件允许替换,替换原则就是依赖注入&br&&br&这个有两个好处,&br&&ol&&li&如果第三方插件被淘汰了,或者你要换服务了,你要做的时候就是重新编写中间件,替换原来的中间件就可以了,只要API相同就行。这样你就无需修改主程序的代码了。&/li&&li&方便设计和测试&br&&/li&&/ol&&br&对于中间件的编写,不是简单封装第三方的API,而是要设计一套符合你主程序的所需要的功能。这中间可以使用一个第三方模块,也可以使用几个第三方模块,把他们的功能柔和成自己想要的功能后,给出中间件API。&br&&br&&br&&br&&br&我曾经想维护一个类似的例子(一样的中间件API,但是不同的第三方组件),不过后来没有时间,就没有继续写下去,不过中间件大致意思到了,只是这个例子没有使用到模块定义和依赖注入。你可以参考一下&br&&a class=& wrap external& href=&//link.zhihu.com/?target=https%3A//github.com/caoglish/msgbox& target=&_blank& rel=&nofollow noreferrer&&caoglish/msgbox · GitHub&/a&
1. 模块定义方式 Javascript 的经典模块定义方式是三种:AMD,CMD 和 UMD AMD 是异步加载模块,天然合适前端。 CMD 是一般加载模块,天然合适后端。 UMD 是通用加载模块,天然前后端都可以使用。 然而现在加载方式,前后端都可以实现加载以上任何一种定义,…
蠢货~为什么要装逼.&br&&br&妹子抱怨了,你就去妹子那边看一下.手把手看一看,然后能解决也别解决,然后聊聊天,扯扯蛋.然后回去再去解决这个问题.&br&如果不懂这个,再来问知乎为什么慢,第二天再过去修复.&br&&br&不管是不是麻烦,一定要装出这个问题很麻烦的样子,然后解决掉.妹子很感谢的样子,然后叫妹子请客吃饭吧.&br&妹子这种时候,不请的话,那你就反请妹子,然后带走.&br&&br&妈的我这种机智的小贱人怎么没有女朋友~~~~~
蠢货~为什么要装逼. 妹子抱怨了,你就去妹子那边看一下.手把手看一看,然后能解决也别解决,然后聊聊天,扯扯蛋.然后回去再去解决这个问题. 如果不懂这个,再来问知乎为什么慢,第二天再过去修复. 不管是不是麻烦,一定要装出这个问题很麻烦的样子,然后解决掉.妹子…
首先你已经不是零基础了。&br&&br&其实这种事情没有什么捷径,亲自动手,一步一步来即可,不能好高骛远。&br&&br&Step 1: 用 HTML + CSS 模仿几个漂亮的静态页面。当你看到现在大部分的网页都觉得能大概猜到怎样做,并且花时间真的能做出来的时候,即可进入下一步。注意,这个时候请你不要管浏览器兼容性或者太过注意代码的优雅结构,因为没必要。做到能兼容现代浏览器,内容和样式基本完全分离即可。这大概需要半个月到一个月的学习时间。&br&&br&Step 2: 用 HTML + CSS + JS 写几个有交互的页面。例如,你可以写一个漂亮的注册页面,它能够验证各种输入是否符合条件并且有一个用原生 JS 实现的日期选择器(Date Picker)。或者,写一个漂亮的,有动画的相册。注意,这个阶段请使用原生 JavaScript。同样的,兼容现代浏览器即可。这大概需要半个月的学习时间。&br&&br&Step 3: 入门一门后端语言。按照你的情况,就 php 吧。有了上面的经验,php 入门之后,相信你能够做一个漂亮的无用户留言版了。请把数据存贮在文件中,因为你还没有学习 SQL 嘛。这大概需要半个月的时间,如果你学习能力强,一个星期也不是没有可能。&br&&br&Step 4: 入门一个关系数据库。比如说 MySQL。DDL 和 CRUD ,请一定要熟练。恩,这个阶段不要谈什么优化,那是扯淡。现在,你大概可以做一个多用户的博客程序了。这大概需要半个月的时间。&br&&br&你看,两个半月不到你就可以成为一个初级的 Web 开发者了。博客做好之后,你可以尝试造更多的轮子。比如:带简单的用户权限的论坛程序、简单的记账工具,等等,做你喜欢做的任何小程序都行。在这个过程中,你会变成一个熟练的初级程序员,或者,你为了偷懒,会学会 jQuery,Smarty 等框架。&br&&br&有一天,你发现你靠写小程序提高不了水平了。接下来就要学习真正的干货了。&br&&ul&&li&学习 C 语言。别问我为什么,我就是觉得一个程序员应该要学过 C 语言,牛逼不牛逼是另外一会事儿,况且很多书都是用的 C 语言描述。别光学语法,弄清编译是什么,链接是什么,指针是又怎么一会事儿。&br&&/li&&li&学习数据结构和简单的算法。你看,你学完 C 语言就能学数据结构和算法了,我难以想象用 php 来描述数据结构和算法会有多么地奇怪。如果你觉得学了之后还是不知道数据结构究竟是什么,有什么用,那证明你还没有真的学到。&br&&/li&&li&学习一门面向对象的静态编程语言。推荐 Java。学得有多好,就看你花了多少时间了。请务必仔细阅读各类相关书籍,深刻领会面向对象的重要编程思想(不过,切忌迷信面向对象编程)。&br&&/li&&li&学习操作系统和计算机网络。至少一些基本的概念需要弄清楚,具体的细节,没有必要过于纠结。&/li&&/ul&Okay...以上都可划为「不求甚解」的阶段,接下来就可以选一个方向(前端,或者后端)「求甚解」了。在「求甚解」的阶段里,我这里就不细说了,也没法儿细说,并且你到了这个阶段,一般是不需要别人告诉你需要学什么了。所以,我只说在进入这个阶段之前,或者刚刚进入这个阶段时,最好去做的一些事情:&br&&ul&&li&看书或文档抛弃中文译本,借助各种工具阅读英文原版。&br&&/li&&li&学习使用 Unix-like 系统。&br&&/li&&li&学会提问[1]。&br&&/li&&li&订阅科技博客,了解业界正在发生什么事情。&/li&&/ul&Happy hacking!&br&&br&[1] 提问的智慧:&a href=&//link.zhihu.com/?target=http%3A//www.wapm.cn/smart-questions/smart-questions-zh.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&wapm.cn/smart-questions&/span&&span class=&invisible&&/smart-questions-zh.html&/span&&span class=&ellipsis&&&/span&&/a&
首先你已经不是零基础了。 其实这种事情没有什么捷径,亲自动手,一步一步来即可,不能好高骛远。 Step 1: 用 HTML + CSS 模仿几个漂亮的静态页面。当你看到现在大部分的网页都觉得能大概猜到怎样做,并且花时间真的能做出来的时候,即可进入下一步。注意,…
就拿淘宝来说说,当作给新人一些科普。&br&&br&先说你看到的页面上,最重要的几个:&br&【搜索商品】——这个功能,如果你有几千条商品,完全可以用select * from tableXX where title like %XX%这样的操作来搞定。但是——当你有(一百亿)条商品的时候,任何一个数据库都无法存放了,请问你怎么搜索?这里需要用到分布式的数据存储方案,另外这个搜索也不可能直接从数据库里来取数据,必然要用到搜索引擎(简单来说搜索引擎更快)。好,能搜出商品了,是否大功告成可以啵一个了呢?早着呢,谁家的商品出现在第一页?这里需要用到巨复杂的排序算法。要是再根据你的购买行为做一些个性化的推荐——这够一帮牛叉的算法工程师奋斗终生了。&br&&br&【商品详情】——就是搜索完毕,看到你感兴趣的,点击查看商品的页面,这个页面有商品的属性、详细描述、评价、卖家信息等等,这个页面的每天展示次数在30亿以上,同样的道理,如果你做一个网站每天有10个人访问,你丝毫感觉不到服务器的压力,但是30亿,要解决的问题就多了去了。首先,这些请求不能直接压到数据库上,任何单机或分布式的数据库,承受30亿每天的压力,都将崩溃到完全没有幸福感,这种情况下要用到的技术就是大规模的分布式缓存,所有的卖家信息、评价信息、商品描述都是从缓存里面来取到的,甚至更加极致的一点“商品的浏览量”这个信息,每打开页面一次都要刷新,你猜能够从缓存里面来取吗?淘宝做到了,整个商品的详情都在缓存里面。&br&&br&【商品图片】——一个商品有5个图片,商品描述里面有更多图片,你猜淘宝有多少张图片要存储?100亿以上。这么多图片要是在你的硬盘里面,你怎么去查找其中的一张?要是你的同学想拷贝你的图片,你需要他准备多少块硬盘?你需要配置多少大的带宽?你们的网卡是否能够承受?你需要多长时间拷贝给他?这样的规模,很不幸市面上已经没有任何商业的解决方案,最终我们必须自己来开发一套存储系统,如果你听说过google的GFS,我们跟他类似,叫TFS。顺便说一下,腾讯也有这样的一套,也叫TFS。&br&&br&【广告系统】——淘宝上有很多广告,什么,你不知道?那说明我们的广告做的还不错,居然很多人不认为它是广告,卖家怎么出价去买淘宝的广告位?广告怎么展示?怎么查看广告效果?这又是一套算法精奇的系统。&br&&br&【BOSS系统】——淘宝的工作人员怎么去管理这么庞大的一个系统,例如某时刻突然宣布某位作家的作品全部从淘宝消失,从数据库到搜索引擎到广告系统,里面的相关数据在几分钟内全部消失,这又需要一个牛叉的后台支撑系统。&br&&br&【运维体系】——支持这么庞大的一个网站,你猜需要多少台服务器?几千台?那是零头。这么多服务器,上面部署什么操作系统,操作系统的内核能否优化?Java虚拟机能否优化?通信模块有没有榨取性能的空间?软件怎么部署上去?出了问题怎么回滚?你装过操作系统吧,优化过吧,被360坑过没,崩溃过没?这里面又有很多门道。&br&&br&不再多写了,除了上面提到的这些,还有很多很多需要做的技术,当然并不是这些东西有多么高不可攀,任何复杂的庞大的东西都是从小到大做起来的,里面需要牛叉到不行的大犇,也需要充满好奇心的菜鸟,最后这一句,你当我是别有用心好了。
就拿淘宝来说说,当作给新人一些科普。 先说你看到的页面上,最重要的几个: 【搜索商品】——这个功能,如果你有几千条商品,完全可以用select * from tableXX where title like %XX%这样的操作来搞定。但是——当你有(一百亿)条商品的时候,…
已有帐号?
无法登录?
社交帐号登录
1987 条内容
3047 人关注
366 条内容
2648 人关注
731 条内容
821 人关注
1855 条内容我从2014年就开始做微信公众号内容的批量采集,最开始的目的是为了做一个html5的垃圾内容网站。当时垃圾站采集到的微信公众号的内容很容易在公众号里面传播。当时批量采集特别好做,采集入口是公众号的历史消息页。这个入口到现在也是一样,只不过越来越难采集了。采集的方式也更新换代了好多个版本。后来在2015年html5垃圾站不做了,转向将采集目标定位在本地新闻资讯类公众号,前端显示做成了app。所以就形成了一个可以自动采集公众号内容的新闻app。曾经我一直担心有一天微信技术升级之后无法采集内容了,我的新闻app就失效了。但随着微信不断的技术升级,采集方法也随之升级,反而使我越来越有信心。只要公众号历史消息页存在,就能批量采集到内容。所以今天决定将采集方法整理之后写下来。我的方法来源于许多同行的分享精神,所以我也会延续这个精神,将我的成果分享出来。&p&&b&本篇文章将持续更新,你所看到的内容将保证在看到的时间是可用的。&/b&&/p&&p&首先我们来看一个微信公众号历史消息页面的链接地址:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MjM5MzczNjY2NA==#wechat_webview_type=1&wechat_redirect
&/code&&/pre&&/div&&p&=========日更新=========&/p&&br&&p&现在根据不同的微信个人号,会出现两种不同的历史消息页面地址,下面是另一种历史消息页的地址,第一种地址的链接会在anyproxy中显示302跳转:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzA3NDk5MjYzNg==&scene=124#wechat_redirect
&/code&&/pre&&/div&&br&&p&第一种链接地址的页面样式:&/p&&p&&figure&&img src=&https://pic3.zhimg.com/v2-f63c8dcbab824_b.jpg& data-rawwidth=&750& data-rawheight=&1334& class=&origin_image zh-lightbox-thumb& width=&750& data-original=&https://pic3.zhimg.com/v2-f63c8dcbab824_r.jpg&&&/figure&第二种链接地址的页面样式:&/p&&p&&figure&&img src=&https://pic1.zhimg.com/v2-a14983b45aad17a068dc636b3556f99f_b.jpg& data-rawwidth=&640& data-rawheight=&1136& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&https://pic1.zhimg.com/v2-a14983b45aad17a068dc636b3556f99f_r.jpg&&&/figure&根据目前掌握的信息,两种页面形式无规律的出现在不同的微信号中,有的微信号始终是第一种页面形式,有的就始终是第二种页面形式。&/p&&p&上面这个链接是一个微信公众号历史消息页面的真实链接,但是我们把这个链接输入到浏览器中会显示:请从微信客户端访问。这是因为实际上这个链接地址还需要几个参数才能正常显示内容。下面我们就来看看可以正常显示内容的完整链接是什么样的:&br&&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&//第一种链接&/span&
&span class=&nx&&http&/span&&span class=&o&&:&/span&&span class=&c1&&//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&/span&
&span class=&c1&&//第二种&/span&
&span class=&nx&&http&/span&&span class=&o&&:&/span&&span class=&c1&&//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&/span&
&/code&&/pre&&/div&&p&&b&这个地址是通过微信客户端打开历史消息页面之后,再使用后面介绍的代理服务器软件获取到的。&/b&这里面有几个参数:&/p&&p&action=;__biz=;uin=;key=;devicetype=;version=;lang=;nettype=;scene=;pass_ticket=;wx_header=;&/p&&p&其中重要的参数是:__uin=;key=;pass_ticket=;这4个参数。&/p&&p&__biz是公众号的一个类似id的参数,每个公众号拥有一个微信的biz,目前极小概率会发生公众号的biz会变化的事件;&/p&&p&剩下的3个参数是有关用户的id和令牌票据之类的意思,&b&这3个参数的值是通过微信的客户端生成后自动补充到地址栏中的。&/b&所以我们想采集公众号就必须通过一个微信客户端app。在以前的微信版本中这3个参数还可以获取一次之后在有效期之内多个公众号通用。现在的版本已经是每次访问一个公众号都会更换参数值。&/p&&p&我现在所使用的方法只需要关注__biz这个参数就可以了。&/p&&br&我的采集系统由以下几部分组成:&p&1、一个微信客户端:可以是一台手机安装了微信的app,或者是用电脑中的安卓模拟器。经过实测ios的微信客户端在批量采集过程中崩溃率高于安卓系统。为了降低成本,我使用的是安卓模拟器。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-414d43c63db7b1d52c74c64b31282fe7_b.jpg& data-rawwidth=&431& data-rawheight=&653& class=&origin_image zh-lightbox-thumb& width=&431& data-original=&https://pic2.zhimg.com/v2-414d43c63db7b1d52c74c64b31282fe7_r.jpg&&&/figure&&br&&p&2、一个微信个人号:为了采集内容不仅需要微信客户端,还要有一个微信个人号专门用于采集,因为这个微信号就干不了其它事情了。&/p&&p&3、本地代理服务器系统:目前使用的方法是通过Anyproxy代理服务器将公众号历史消息页面中的文章列表发送到自己的服务器上。具体安装设置方法在后面详细介绍。&/p&&p&4、文章列表分析与入库系统:我用的是php语言编写的,后文将详细介绍如何分析文章列表和建立采集队列实现批量采集内容。&/p&&p&步骤&/p&&p&一、安装模拟器或使用手机安装微信客户端app,申请微信个人号并登录到app上面。这一点就不过多介绍了,大家都会。&/p&&p&二、代理服务器系统安装&/p&&p&目前我使用的是Anyproxy,&a href=&https://link.zhihu.com/?target=http%3A//anyproxy.io& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&AnyProxy&/a& 。这个软件的特点是可以获取到https链接的内容。在2016年年初的时候微信公众号和微信文章开始使用https链接。并且Anyproxy可以通过修改rule配置实现向公众号的页面中插入脚本代码。下面开始介绍安装与配置过程。&/p&&p&1、安装 &a href=&https://link.zhihu.com/?target=http%3A//nodejs.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&NodeJS&/a&&/p&&p&2、在命令行或者终端运行 npm install -g anyproxy,mac系统需要加上sudo;&/p&&p&3、生成RootCA,https需要这个证书:运行命令sudo anyproxy --root(windows可能不需要sudo);&/p&&p&4、启动anyproxy运行命令:sudo anyproxy -i;参数-i是解析HTTPS的意思;&/p&&br&&p&5、安装证书,在手机或安卓模拟器中安装证书:&/p&&ul&&li&方法一: 启动anyproxy,浏览器打开 &a href=&https://link.zhihu.com/?target=http%3A//localhost%3A8002/fetchCrtFile& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&localhost:8002/fetchCrt&/span&&span class=&invisible&&File&/span&&span class=&ellipsis&&&/span&&/a& ,能获取rootCA.crt文件&br&&/li&&li&方法二:启动anyproxy,&a href=&https://link.zhihu.com/?target=http%3A//localhost%3A8002/qr_root& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&localhost:8002/qr_root&/span&&span class=&invisible&&&/span&&/a& 可以获取证书路径的二维码,移动端安装时会比较便捷&br&&/li&&li&建议通过二维码将证书安装到手机中。&/li&&/ul&&br&&p&6、设置代理:安卓模拟器的代理服务器地址是wifi链接的网关,可以通过吧dhcp设置为静态后看到网关地址,看完后别忘了再设置为自动。手机中的代理服务器地址就是运行anyproxy的电脑的ip地址。代理服务器默认端口是8001;&/p&&figure&&img src=&https://pic2.zhimg.com/v2-f8d269f0567efeee6b1f83_b.jpg& data-rawwidth=&431& data-rawheight=&653& class=&origin_image zh-lightbox-thumb& width=&431& data-original=&https://pic2.zhimg.com/v2-f8d269f0567efeee6b1f83_r.jpg&&&/figure&&p&现在打开微信,点击到任意一个公众号历史消息或文章中,在终端都可以看到响应的代码滚动。如果没有出现,请检查手机的代理设置是否正确。&figure&&img src=&https://pic4.zhimg.com/v2-ddc05be32f5dc14dbc827_b.jpg& data-rawwidth=&1193& data-rawheight=&604& class=&origin_image zh-lightbox-thumb& width=&1193& data-original=&https://pic4.zhimg.com/v2-ddc05be32f5dc14dbc827_r.jpg&&&/figure&&/p&&p&现在打开浏览器地址&a href=&https://link.zhihu.com/?target=http%3A//localhost%3A8002& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&localhost:8002&/span&&span class=&invisible&&&/span&&/a& 可以看到anyproxy的web界面。从微信中点开一个历史消息页面,然后再看浏览器的web界面,会滚动出现历史消息页面的地址。&/p&&p&&figure&&img src=&https://pic1.zhimg.com/v2-45bcbcfad12d8_b.jpg& data-rawwidth=&1165& data-rawheight=&686& class=&origin_image zh-lightbox-thumb& width=&1165& data-original=&https://pic1.zhimg.com/v2-45bcbcfad12d8_r.jpg&&&/figure&以/mp/getmasssendmsg开头的网址就是微信历史消息页面。左边一个小锁头表示这个页面是https加密的。现在我们点击一下这一行;&br&&/p&&p&=========日更新=========&br&&/p&&p&部分微信号以/mp/getmasssendmsg开头的网址会出现302跳转,跳转到了/mp/profile_ext?action=home开头的地址。所以点开这个地址才可以看到内容。&/p&&br&&p&&figure&&img src=&https://pic2.zhimg.com/v2-290cede650af43ba98f6f2f5ae81d06b_b.jpg& data-rawwidth=&1165& data-rawheight=&686& class=&origin_image zh-lightbox-thumb& width=&1165& data-original=&https://pic2.zhimg.com/v2-290cede650af43ba98f6f2f5ae81d06b_r.jpg&&&/figure&右边如果出现了html的文件内容则表示解密成功。如果没有内容,请检查anyproxy的运行模式是否有参数i,是否生成了ca证书,手机是否正确安装证书。&/p&&p&现在我们的手机中的所有内容都已经可以明文通过代理服务器了。下面我们要修改配置代理服务器,使公众号内容被获取到。&/p&&p&一、找到配置文件:&/p&&p&mac系统中配置文件的位置在/usr/local/lib/node_modules/anyproxy/lib/;windows系统请原谅我暂时不知道。应该可以根据类似mac的文件夹地址找到这个目录。&/p&&p&二、修改文件rule_default.js&/p&&p&找到replaceServerResDataAsync: function(req,res,serverResData,callback) 函数&/p&&p&修改函数内容(请注意详细阅读注释,这里只是介绍原理,理解后根据自己的条件修改内容):&/p&&p&=========日更新=========&br&&/p&&br&&p&因为出现了两种页面形式,且在不同的微信号中始终显示同一种页面形式,但为了能兼容两种页面形式,以下的代码会保留两种页面形式的判断,你也可以根据自己的页面形式去掉li&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&replaceServerResDataAsync&/span&&span class=&o&&:&/span& &span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&req&/span&&span class=&p&&,&/span&&span class=&nx&&res&/span&&span class=&p&&,&/span&&span class=&nx&&serverResData&/span&&span class=&p&&,&/span&&span class=&nx&&callback&/span&&span class=&p&&){&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&sr&&/mp\/getmasssendmsg/i&/span&&span class=&p&&.&/span&&span class=&nx&&test&/span&&span class=&p&&(&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&)){&/span&&span class=&c1&&//当链接地址为公众号历史消息页面时(第一种页面形式)&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&.&/span&&span class=&nx&&toString&/span&&span class=&p&&()&/span& &span class=&o&&!==&/span& &span class=&s2&&&&&/span&&span class=&p&&){&/span&
&span class=&k&&try&/span& &span class=&p&&{&/span&&span class=&c1&&//防止报错退出程序&/span&
&span class=&kd&&var&/span& &span class=&nx&&reg&/span& &span class=&o&&=&/span& &span class=&sr&&/msgList = (.*?);/&/span&&span class=&p&&;&/span&&span class=&c1&&//定义历史消息正则匹配规则&/span&
&span class=&kd&&var&/span& &span class=&nx&&ret&/span& &span class=&o&&=&/span& &span class=&nx&&reg&/span&&span class=&p&&.&/span&&span class=&nx&&exec&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&.&/span&&span class=&nx&&toString&/span&&span class=&p&&());&/span&&span class=&c1&&//转换变量为string&/span&
&span class=&nx&&HttpPost&/span&&span class=&p&&(&/span&&span class=&nx&&ret&/span&&span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&],&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&,&/span&&span class=&s2&&&getMsgJson.php&&/span&&span class=&p&&);&/span&&span class=&c1&&//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器&/span&
&span class=&kd&&var&/span& &span class=&nx&&http&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'http'&/span&&span class=&p&&);&/span&
&span class=&nx&&http&/span&&span class=&p&&.&/span&&span class=&nx&&get&/span&&span class=&p&&(&/span&&span class=&s1&&'http://xxx.com/getWxHis.php'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&res&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&&span class=&c1&&//这个地址是自己服务器上的一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxHis.php的原理。&/span&
&span class=&nx&&res&/span&&span class=&p&&.&/span&&span class=&nx&&on&/span&&span class=&p&&(&/span&&span class=&s1&&'data'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&chunk&/span&&span class=&p&&){&/span&
&span class=&nx&&callback&/span&&span class=&p&&(&/span&&span class=&nx&&chunk&/span&&span class=&o&&+&/span&&span class=&nx&&serverResData&/span&&span class=&p&&);&/span&&span class=&c1&&//将返回的代码插入到历史消息页面中,并返回显示出来&/span&
&span class=&p&&})&/span&
&span class=&p&&});&/span&
&span class=&p&&}&/span&&span class=&k&&catch&/span&&span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&){&/span&&span class=&c1&&//如果上面的正则没有匹配到,那么这个页面内容可能是公众号历史消息页面向下翻动的第二页,因为历史消息第一页是html格式的,第二页就是json格式的。&/span&
&span class=&k&&try&/span& &span class=&p&&{&/span&
&span class=&kd&&var&/span& &span class=&nx&&json&/span& &span class=&o&&=&/span& &span class=&nx&&JSON&/span&&span class=&p&&.&/span&&span class=&nx&&parse&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&.&/span&&span class=&nx&&toString&/span&&span class=&p&&());&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nx&&json&/span&&span class=&p&&.&/span&&span class=&nx&&general_msg_list&/span& &span class=&o&&!=&/span& &span class=&p&&[])&/span& &span class=&p&&{&/span&
&span class=&nx&&HttpPost&/span&&span class=&p&&(&/span&&span class=&nx&&json&/span&&span class=&p&&.&/span&&span class=&nx&&general_msg_list&/span&&span class=&p&&,&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&,&/span&&span class=&s2&&&getMsgJson.php&&/span&&span class=&p&&);&/span&&span class=&c1&&//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&&span class=&k&&catch&/span&&span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&){&/span&
&span class=&nx&&console&/span&&span class=&p&&.&/span&&span class=&nx&&log&/span&&span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&);&/span&&span class=&c1&&//错误捕捉&/span&
&span class=&p&&}&/span&
&span class=&nx&&callback&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&);&/span&&span class=&c1&&//直接返回第二页json内容&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&&span class=&k&&else&/span& &span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&sr&&/mp\/profile_ext\?action=home/i&/span&&span class=&p&&.&/span&&span class=&nx&&test&/span&&span class=&p&&(&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&)){&/span&&span class=&c1&&//当链接地址为公众号历史消息页面时(第二种页面形式)&/span&
&span class=&k&&try&/span& &span class=&p&&{&/span&
&span class=&kd&&var&/span& &span class=&nx&&reg&/span& &span class=&o&&=&/span& &span class=&sr&&/var msgList = \'(.*?)\';/&/span&&span class=&p&&;&/span&&span class=&c1&&//定义历史消息正则匹配规则(和第一种页面形式的正则不同)&/span&
&span class=&kd&&var&/span& &span class=&nx&&ret&/span& &span class=&o&&=&/span& &span class=&nx&&reg&/span&&span class=&p&&.&/span&&span class=&nx&&exec&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&.&/span&&span class=&nx&&toString&/span&&span class=&p&&());&/span&&span class=&c1&&//转换变量为string&/span&
&span class=&nx&&HttpPost&/span&&span class=&p&&(&/span&&span class=&nx&&ret&/span&&span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&],&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&,&/span&&span class=&s2&&&getMsgJson.php&&/span&&span class=&p&&);&/span&&span class=&c1&&//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器&/span&
&span class=&kd&&var&/span& &span class=&nx&&http&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'http'&/span&&span class=&p&&);&/span&
&span class=&nx&&http&/span&&span class=&p&&.&/span&&span class=&nx&&get&/span&&span class=&p&&(&/span&&span class=&s1&&'http://xxx.com/getWxHis'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&res&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&&span class=&c1&&//这个地址是自己服务器上的一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxHis.php的原理。&/span&
&span class=&nx&&res&/span&&span class=&p&&.&/span&&span class=&nx&&on&/span&&span class=&p&&(&/span&&span class=&s1&&'data'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&chunk&/span&&span class=&p&&){&/span&
&span class=&nx&&callback&/span&&span class=&p&&(&/span&&span class=&nx&&chunk&/span&&span class=&o&&+&/span&&span class=&nx&&serverResData&/span&&span class=&p&&);&/span&&span class=&c1&&//将返回的代码插入到历史消息页面中,并返回显示出来&/span&
&span class=&p&&})&/span&
&span class=&p&&});&/span&
&span class=&p&&}&/span&&span class=&k&&catch&/span&&span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&){&/span&
&span class=&nx&&callback&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&&span class=&k&&else&/span& &span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&sr&&/mp\/profile_ext\?action=getmsg/i&/span&&span class=&p&&.&/span&&span class=&nx&&test&/span&&span class=&p&&(&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&)){&/span&&span class=&c1&&//第二种页面表现形式的向下翻页后的json&/span&
&span class=&k&&try&/span& &span class=&p&&{&/span&
&span class=&kd&&var&/span& &span class=&nx&&json&/span& &span class=&o&&=&/span& &span class=&nx&&JSON&/span&&span class=&p&&.&/span&&span class=&nx&&parse&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&.&/span&&span class=&nx&&toString&/span&&span class=&p&&());&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nx&&json&/span&&span class=&p&&.&/span&&span class=&nx&&general_msg_list&/span& &span class=&o&&!=&/span& &span class=&p&&[])&/span& &span class=&p&&{&/span&
&span class=&nx&&HttpPost&/span&&span class=&p&&(&/span&&span class=&nx&&json&/span&&span class=&p&&.&/span&&span class=&nx&&general_msg_list&/span&&span class=&p&&,&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&,&/span&&span class=&s2&&&getMsgJson.php&&/span&&span class=&p&&);&/span&&span class=&c1&&//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&&span class=&k&&catch&/span&&span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&){&/span&
&span class=&nx&&console&/span&&span class=&p&&.&/span&&span class=&nx&&log&/span&&span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&nx&&callback&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&&span class=&k&&else&/span& &span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&sr&&/mp\/getappmsgext/i&/span&&span class=&p&&.&/span&&span class=&nx&&test&/span&&span class=&p&&(&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&)){&/span&&span class=&c1&&//当链接地址为公众号文章阅读量和点赞量时&/span&
&span class=&k&&try&/span& &span class=&p&&{&/span&
&span class=&nx&&HttpPost&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&,&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&,&/span&&span class=&s2&&&getMsgExt.php&&/span&&span class=&p&&);&/span&&span class=&c1&&//函数是后文定义的,功能是将文章阅读量点赞量的json发送到服务器&/span&
&span class=&p&&}&/span&&span class=&k&&catch&/span&&span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&){&/span&
&span class=&p&&}&/span&
&span class=&nx&&callback&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&&span class=&k&&else&/span& &span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&sr&&/s\?__biz/i&/span&&span class=&p&&.&/span&&span class=&nx&&test&/span&&span class=&p&&(&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&)&/span& &span class=&o&&||&/span& &span class=&sr&&/mp\/rumor/i&/span&&span class=&p&&.&/span&&span class=&nx&&test&/span&&span class=&p&&(&/span&&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&url&/span&&span class=&p&&)){&/span&&span class=&c1&&//当链接地址为公众号文章时(rumor这个地址是公众号文章被辟谣了)&/span&
&span class=&k&&try&/span& &span class=&p&&{&/span&
&span class=&kd&&var&/span& &span class=&nx&&http&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'http'&/span&&span class=&p&&);&/span&
&span class=&nx&&http&/span&&span class=&p&&.&/span&&span class=&nx&&get&/span&&span class=&p&&(&/span&&span class=&s1&&'http://xxx.com/getWxPost.php'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&res&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&&span class=&c1&&//这个地址是自己服务器上的另一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxPost.php的原理。&/span&
&span class=&nx&&res&/span&&span class=&p&&.&/span&&span class=&nx&&on&/span&&span class=&p&&(&/span&&span class=&s1&&'data'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&chunk&/span&&span class=&p&&){&/span&
&span class=&nx&&callback&/span&&span class=&p&&(&/span&&span class=&nx&&chunk&/span&&span class=&o&&+&/span&&span class=&nx&&serverResData&/span&&span class=&p&&);&/span&
&span class=&p&&})&/span&
&span class=&p&&});&/span&
&span class=&p&&}&/span&&span class=&k&&catch&/span&&span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&){&/span&
&span class=&nx&&callback&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&&span class=&k&&else&/span&&span class=&p&&{&/span&
&span class=&nx&&callback&/span&&span class=&p&&(&/span&&span class=&nx&&serverResData&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&p&&},&/span&
&/code&&/pre&&/div&&br&&p&上面这段代码是利用anyproxy可以修改返回页面内容的功能,向页面注入脚本,和将页面内容发送到服务器上。使用这个原理来批量采集公众号内容和阅读量。这段脚本中自定义了一个函数,下面详细介绍:&/p&&p&在rule_default.js文件末尾添加以下代码:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kd&&function&/span& &span class=&nx&&HttpPost&/span&&span class=&p&&(&/span&&span class=&nx&&str&/span&&span class=&p&&,&/span&&span class=&nx&&url&/span&&span class=&p&&,&/span&&span class=&nx&&path&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&&span class=&c1&&//将json发送到服务器,str为json内容,url为历史消息页面地址,path是接收程序的路径和文件名&/span&
&span class=&kd&&var&/span& &span class=&nx&&http&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'http'&/span&&span class=&p&&);&/span&
&span class=&kd&&var&/span& &span class=&nx&&data&/span& &span class=&o&&=&/span& &span class=&p&&{&/span&
&span class=&nx&&str&/span&&span class=&o&&:&/span& &span class=&nb&&encodeURIComponent&/span&&span class=&p&&(&/span&&span class=&nx&&str&/span&&span class=&p&&),&/span&
&span class=&nx&&url&/span&&span class=&o&&:&/span& &span class=&nb&&encodeURIComponent&/span&&span class=&p&&(&/span&&span class=&nx&&url&/span&&span class=&p&&)&/span&
&span class=&p&&};&/span&
&span class=&nx&&content&/span& &span class=&o&&=&/span& &span class=&nx&&require&/span&&span class=&p&&(&/span&&span class=&s1&&'querystring'&/span&&span class=&p&&).&/span&&span class=&nx&&stringify&/span&&span class=&p&&(&/span&&span class=&nx&&data&/span&&span class=&p&&);&/span&
&span class=&kd&&var&/span& &span class=&nx&&options&/span& &span class=&o&&=&/span& &span class=&p&&{&/span&
&span class=&nx&&method&/span&&span class=&o&&:&/span& &span class=&s2&&&POST&&/span&&span class=&p&&,&/span&
&span class=&nx&&host&/span&&span class=&o&&:&/span& &span class=&s2&&&www.xxx.com&&/span&&span class=&p&&,&/span&&span class=&c1&&//注意没有http://,这是服务器的域名。&/span&
&span class=&nx&&port&/span&&span class=&o&&:&/span& &span class=&mi&&80&/span&&span class=&p&&,&/span&
&span class=&nx&&path&/span&&span class=&o&&:&/span& &span class=&nx&&path&/span&&span class=&p&&,&/span&&span class=&c1&&//接收程序的路径和文件名&/span&
&span class=&nx&&headers&/span&&span class=&o&&:&/span& &span class=&p&&{&/span&
&span class=&s1&&'Content-Type'&/span&&span class=&o&&:&/span& &span class=&s1&&'application/x-www-form- charset=UTF-8'&/span&&span class=&p&&,&/span&
&span class=&s2&&&Content-Length&&/span&&span class=&o&&:&/span& &span class=&nx&&content&/span&&span class=&p&&.&/span&&span class=&nx&&length&/span&
&span class=&p&&}&/span&
&span class=&p&&};&/span&
&span class=&kd&&var&/span& &span class=&nx&&req&/span& &span class=&o&&=&/span& &span class=&nx&&http&/span&&span class=&p&&.&/span&&span class=&nx&&request&/span&&span class=&p&&(&/span&&span class=&nx&&options&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&res&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&res&/span&&span class=&p&&.&/span&&span class=&nx&&setEncoding&/span&&span class=&p&&(&/span&&span class=&s1&&'utf8'&/span&&span class=&p&&);&/span&
&span class=&nx&&res&/span&&span class=&p&&.&/span&&span class=&nx&&on&/span&&span class=&p&&(&/span&&span class=&s1&&'data'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&chunk&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&console&/span&&span class=&p&&.&/span&&span class=&nx&&log&/span&&span class=&p&&(&/span&&span class=&s1&&'BODY: '&/span& &span class=&o&&+&/span& &span class=&nx&&chunk&/span&&span class=&p&&);&/span&
&span class=&p&&});&/span&
&span class=&p&&});&/span&
&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&on&/span&&span class=&p&&(&/span&&span class=&s1&&'error'&/span&&span class=&p&&,&/span& &span class=&kd&&function&/span& &span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&console&/span&&span class=&p&&.&/span&&span class=&nx&&log&/span&&span class=&p&&(&/span&&span class=&s1&&'problem with request: '&/span& &span class=&o&&+&/span& &span class=&nx&&e&/span&&span class=&p&&.&/span&&span class=&nx&&message&/span&&span class=&p&&);&/span&
&span class=&p&&});&/span&
&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&write&/span&&span class=&p&&(&/span&&span class=&nx&&content&/span&&span class=&p&&);&/span&
&span class=&nx&&req&/span&&span class=&p&&.&/span&&span class=&nx&&end&/span&&span class=&p&&();&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&上面就是rule规则修改的主要部分,需要将json内容发送到自己的服务器,还要从服务器获取到下一页的跳转地址。这就涉及到了四个php文件:getMsgJson.php、getMsgExt.php、getWxHis.php、getWxPost.php&/p&&br&&p&在详细介绍这4个php文件之前,为了提高采集系统性能和降低崩溃率,我们还可以进行一些修改:&/p&&p&安卓模拟器经常会访问一些&a href=&https://link.zhihu.com/?target=http%3A//google.com& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&google.com&/span&&span class=&invisible&&&/span&&/a&的地址,这样会导致anyproxy死机,找到函数replaceRequestOption : function(req,option),修改函数内容:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&nx&&replaceRequestOption&/span& &span class=&o&&:&/span& &span class=&kd&&function&/span&&span class=&p&&(&/span&&span class=&nx&&req&/span&&span class=&p&&,&/span&&span class=&nx&&option&/span&&span class=&p&&){&/span&
&span class=&kd&&var&/span& &span class=&nx&&newOption&/span& &span class=&o&&=&/span& &span class=&nx&&option&/span&&span class=&p&&;&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&sr&&/google/i&/span&&span class=&p&&.&/span&&span class=&nx&&test&/span&&span class=&p&&(&/span&&span class=&nx&&newOption&/span&&span class=&p&&.&/span&&span class=&nx&&headers&/span&&span class=&p&&.&/span&&span class=&nx&&host&/span&&span class=&p&&)){&/span&
&span class=&nx&&newOption&/span&&span class=&p&&.&/span&&span class=&nx&&hostname&/span& &span class=&o&&=&/span& &span class=&s2&&&www.baidu.com&&/span&&span class=&p&&;&/span&
&span class=&nx&&newOption&/span&&span class=&p&&.&/span&&span class=&nx&&port&/span&
&span class=&o&&=&/span& &span class=&s2&&&80&&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&k&&return&/span& &span class=&nx&&newOption&/span&&span class=&p&&;&/span&
&span class=&p&&},&/span&
&/code&&/pre&&/div&&p&以上就是针对anyproxy的rule文件的修改配置,配置修改完成之后,重新启动anyproxy。mac系统里按control+c中断程序,再输入命令sudo anyproxy -i启动;如果启动报错,可能是程序没有退出干净,端口被占用。这时输入命令ps -a查看占用的pid,再输入命令“kill -9 pid”这里将pid替换成查询到的pid号码。杀死进程之后就可以启动anyproxy了。还是那句话windows的命令请原谅我不太熟悉。&/p&&br&&p&接下来详细介绍服务器上接收程序的设计原理:&/p&&p&(以下代码并不是直接可以用的,只是介绍原理,其中一部分需要根据自己的服务器数据库框架进行编写)&/p&&p&1、getMsgJson.php:这个程序负责接收历史消息的json并解析后存入数据库&/p&&div class=&highlight&&&pre&&code class=&language-php&&&span&&/span&&span class=&cp&&&?&/span&
&span class=&nv&&$str&/span& &span class=&o&&=&/span& &span class=&nv&&$_POST&/span&&span class=&p&&[&/span&&span class=&s1&&'str'&/span&&span class=&p&&];&/span&
&span class=&nv&&$url&/span& &span class=&o&&=&/span& &span class=&nv&&$_POST&/span&&span class=&p&&[&/span&&span class=&s1&&'url'&/span&&span class=&p&&];&/span&&span class=&c1&&//先获取到两个POST变量&/span&
&span class=&c1&&//先针对url参数进行操作&/span&
&span class=&nb&&parse_str&/span&&span class=&p&&(&/span&&span class=&nb&&parse_url&/span&&span class=&p&&(&/span&&span class=&nb&&htmlspecialchars_decode&/span&&span class=&p&&(&/span&&span class=&nb&&urldecode&/span&&span class=&p&&(&/span&&span class=&nv&&$url&/span&&span class=&p&&)),&/span&&span class=&nx&&PHP_URL_QUERY&/span& &span class=&p&&),&/span&&span class=&nv&&$query&/span&&span class=&p&&);&/span&&span class=&c1&&//解析url地址&/span&
&span class=&nv&&$biz&/span& &span class=&o&&=&/span& &span class=&nv&&$query&/span&&span class=&p&&[&/span&&span class=&s1&&'__biz'&/span&&span class=&p&&];&/span&&span class=&c1&&//得到公众号的biz&/span&
&span class=&c1&&//接下来进行以下操作&/span&
&span class=&c1&&//从数据库中查询biz是否已经存在,如果不存在则插入,这代表着我们新添加了一个采集目标公众号。&/span&
&span class=&c1&&//再解析str变量&/span&
&span class=&nv&&$json&/span& &span class=&o&&=&/span& &span class=&nb&&json_decode&/span&&span class=&p&&(&/span&&span class=&nv&&$str&/span&&span class=&p&&,&/span&&span class=&k&&true&/span&&span class=&p&&);&/span&&span class=&c1&&//首先进行json_decode&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&o&&!&/span&&span class=&nv&&$json&/span&&span class=&p&&){&/span&
&span class=&nv&&$json&/span& &span class=&o&&=&/span& &span class=&nb&&json_decode&/span&&span class=&p&&(&/span&&span class=&nb&&htmlspecialchars_decode&/span&&span class=&p&&(&/span&&span class=&nv&&$str&/span&&span class=&p&&),&/span&&span class=&k&&true&/span&&span class=&p&&);&/span&&span class=&c1&&//如果不成功,就增加一步htmlspecialchars_decode&/span&
&span class=&p&&}&/span&
&span class=&k&&foreach&/span&&span class=&p&&(&/span&&span class=&nv&&$json&/span&&span class=&p&&[&/span&&span class=&s1&&'list'&/span&&span class=&p&&]&/span& &span class=&k&&as&/span& &span class=&nv&&$k&/span&&span class=&o&&=&&/span&&span class=&nv&&$v&/span&&span class=&p&&){&/span&
&span class=&nv&&$type&/span& &span class=&o&&=&/span& &span class=&nv&&$v&/span&&span class=&p&&[&/span&&span class=&s1&&'comm_msg_info'&/span&&span class=&p&&][&/span&&span class=&s1&&'type'&/span&&span class=&p&&];&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&nv&&$type&/span&&span class=&o&&==&/span&&span class=&mi&&49&/span&&span class=&p&&){&/span&&span class=&c1&&//type=49代表是图文消息&/span&
&span class=&nv&&$content_url&/span& &span class=&o&&=&/span& &span class=&nb&&str_replace&/span&&span class=&p&&(&/span&&span class=&s2&&&&/span&&span class=&se&&\\&/span&&span class=&s2&&&&/span&&span class=&p&&,&/span& &span class=&s2&&&&&/span&&span class=&p&&,&/span& &span class=&nb&&htmlspecialchars_decode&/span&&span class=&p&&(&/span&&span class=&nv&&$v&/span&&span class=&p&&[&/span&&span class=&s1&&'app_msg_ext_info'&/span&&span class=&p&&][&/span&&span class=&s1&&'content_url'&/span&&span class=&p&&]));&/span&&span class=&c1&&//获得图文消息的链接地址&/span&
&span class=&nv&&$is_multi&/span& &span class=&o&&=&/span& &span class=&nv&&$v&/span&&span class=&p&&[&/span&&span class=&s1&&'app_msg_ext_info'&/span&&span class=&p&&][&/span&&span class=&s1&&'is_multi'&/span&&span class=&p&&];&/span&&span class=&c1&&//是否是多图文消息&/span&
&span class=&nv&&$datetime&/span& &span class=&o&&=&/span& &span class=&nv&&$v&/span&&span class=&p&&[&/span&&span class=&s1&&'comm_msg_info'&/span&&span class=&p&&][&/span&&span class=&s1&&'datetime'&/span&&span class=&p&&];&/span&&span class=&c1&&//图文消息发送时间&/span&
&span class=&c1&&//在这里将图文消息链接地址插入到采集队列库中(队列库将在后文介绍,主要目的是建立一个批量采集队列,另一个程序将根据队列安排下一个采集的公众号或者文章内容)&/span&
&span class=&c1&&//在这里根据$content_url从数据库中判断一下是否重复&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&s1&&'数据库中不存在相同的$content_url'&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nv&&$fileid&/span& &span class=&o&&=&/span& &span class=&nv&&$v&/span&&span class=&p&&[&/span&&span class=&s1&&'app_msg_ext_info'&/span&&span class=&p&&][&/span&&span class=&s1&&'fileid'&/span&&span class=&p&&];&/span&&span class=&c1&&//一个微信给的id&/span&
&span class=&nv&&$title&/span& &span class=&o&&=&/span& &span class=&nv&&$v&/span&&span class=&p&&[&/span&&span class=&s1&&'app_msg_ext_info'&/span&&span class=&p&&][&/span&&span class=&s1&&'title'&/span&&span class=&p&&];&/span&&span class=&c1&&//文章标题&/span&
&span class=&nv&&$title_encode&/span& &span class=&o&&=&/span& &span class=&nb&&urlencode&/span&&span class=&p&&(&/span&&span class=&nb&&str_replace&/span&&span class=&p&&(&/span&&span class=&s2&&&&&&/span&&span class=&p&&,&/span& &span class=&s2&&&&&/span&&span class=&p&&,&/span& &span class=&nv&&$title&/span&&span class=&p&&));&/span&&span class=&c1&&//建议将标题进行编码,这样就可以存储emoji特殊符号了&/span&
&span class=&nv&&$digest&/span& &span class=&o&&=&/span& &span class=&nv&&$v&/span&&span class=&p&&[&/span&&span class=&s1&&'app_msg_ext_info'&/span&&span class=&p&&][&/span&&span class=&s1&&'digest'&/span&&span class=&p&&];&/span&&span class=&c1&&//文章摘要&/span&
&span class=&nv&&$source_url&/span& &span class=&o&&=&/span& &span class=&nb&&str_replace&/span&&span class=&p&&(&/span&&span class=&s2&&&&/span&&span class=&se&&\\&/span&&span class=&s2&&&&/span&&span class=&p&&,&/span& &span class=&s2&&&&&/span&&span class=&p&&,&/span& &span class=&nb&&htmlspecialchars_decode&/span&&span class=&p&&(&/span&&span class=&nv&&$v&/span&&span class=&p&&[&/span&&span class=&s1&&'app_msg_ext_info'&/span&&span class=&p&&][&/span&&span class=&s1&&'source_url'&/span&&span class=&p&&]));&/span&&span class=&c1&&//阅读原文的链接&/span&
&span class=&nv&&$cover&/span& &span class=&o&&=&/span& &span class=&nb&&str_replace&/span&&span class=&p&&(&/span&&span class=&s2&&&&/span&&span class=&se&&\\&/span&&span class=&s2&&&&/span&&span class=&p&&,&/span& &span class=&s2&&&&&/span&&span class=&p&&,&/span& &span class=&nb&&htmlspecialchars_decode&/span&&span class=&p&&(&/span&&span class=&nv&&$v&/span&&span class=&p&&[&/span&&span class=&s1&&'app_msg_ext_info'&/span&&span class=&p&&][&/span&&span class=&s1&&'cover'&/span&&span class=&p&&]));&/span&&span class=&c1&&//封面图片&/span&
&span class=&nv&&$is_top&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&&span class=&c1&&//标记一下是头条内容&/span&
&span class=&c1&&//现在存入数据库&/span&
&span class=&k&&echo&/span& &span class=&s2&&&头条标题:&&/span&&span class=&o&&.&/span&&span class=&nv&&$title&/span&&span class=&o&&.&/span&&span class=&nv&&$lastId&/span&&span class=&o&&.&/span&&span class=&s2&&&&/span&&span class=&se&&\n&/span&&span class=&s2&&&&/span&&span class=&p&&;&/span&&span class=&c1&&//这个echo可以显示在anyproxy的终端里&/span&
&span class=&p&&}&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&nv&&$is_multi&/span&&span class=&o&&==&/span&&span class=&mi&&1&/span&&span class=&p&&){&/span&&span class=&c1&&//如果是多图文消息&/span&
&span class=&k&&foreach&/span&&span class=&p&&(&/span&&span class=&nv&&$v&/span&&span class=&p&&[&/span&&span class=&s1&&'app_msg_ext_info'&/span&&span class=&p&&][&/span&&span class=&s1&&'multi_app_msg_item_list'&/span&&span class=&p&&]&/span& &span class=&k&&as&/span& &span class=&nv&&$kk&/span&&span class=&o&&=&&/span&&span class=&nv&&$vv&/span&&span class=&p&&){&/span&&span class=&c1&&//循环后面的图文消息&/span&
&span class=&nv&&$content_url&/span& &span class=&o&&=&/span& &span class=&nb&&str_replace&/span&&span class=&p&&(&/span&&span class=&s2&&&&/span&&span class=&se&&\\&/span&&span class=&s2&&&&/span&&span class=&p&&,&/span&&span class=&s2&&&&&/span&&span class=&p&&,&/span&&span class=&nb&&htmlspecialchars_decode&/span&&span class=&p&&(&/span&&span class=&nv&&$vv&/span&&span class=&p&&[&/span&&span class=&s1&&'content_url'&/span&&span class=&p&&]));&/span&&span class=&c1&&//图文消息链接地址&/span&
&span class=&c1&&//这里再次根据$content_url判断一下数据库中是否重复以免出错&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&s1&&'数据库中不存在相同的$content_url'&/span&&span class=&p&&){&/span&
&span class=&c1&&//在这里将图文消息链接地址插入到采集队列库中(队列库将在后文介绍,主要目的是建立一个批量采集队列,另一个程序将根据队列安排下一个采集的公众号或者文章内容)&/span&
&span class=&nv&&$title&/span& &span class=&o&&=&/span& &span class=&nv&&$vv&/span&&span class=&p&&[&/span&&span class=&s1&&'title'&/span&&span class=&p&&];&/span&&span class=&c1&&//文章标题&/span&
&span class=&nv&&$fileid&/span& &span class=&o&&=&/span& &span class=&nv&&$vv&/span&&span class=&p&&[&/span&&span class=&s1&&'fileid'&/span&&span class=&p&&];&/span&&span class=&c1&&//一个微信给的id&/span&
&span class=&nv&&$title_encode&/span& &span class=&o&&=&/span& &span class=&nb&&urlencode&/span&&span class=&p&&(&/span&&span class=&nb&&str_replace&/span&&span class=&p&&(&/span&&span class=&s2&&&&&&/span&&span class=&p&&,&/span&&span class=&s2&&&&&/span&&span class=&p&&,&/span&&span class=&nv&&$title&/span&&span class=&p&&));&/span&&span class=&c1&&//建议将标题进行编码,这样就可以存储emoji特殊符号了&/span&
&span class=&nv&&$digest&/span& &span class=&o&&=&/span& &span class=&nb&&htmlspecialchars&/span&&span class=&p&&(&/span&&span class=&nv&&$vv&/span&&span class=&p&&[&/span&&span class=&s1&&'digest'&/span&&span class=&p&&]);&/span&&span class=&c1&&//文章摘要&/span&
&span class=&nv&&$source_url&/span& &span class=&o&&=&/span& &span class=&nb&&str_replace&/span&&span class=&p&&(&/span&&span class=&s2&&&&/span&&span class=&se&&\\&/span&&span class=&s2&&&&/span&&span class=&p&&,&/span&&span class=&s2&&&&&/span&&span class=&p&&,&/span&&span class=&nb&&htmlspecialchars_decode&/span&&span class=&p&&(&/span&&span class=&nv&&$vv&/span&&span class=&p&&[&/span&&span class=&s1&&'source_url'&/span&&span class=&p&&]));&/span&&span class=&c1&&//阅读原文的链接&/span&
&span class=&c1&&//$cover = getCover(str_replace(&\\&,&&,htmlspecialchars_decode($vv['cover'])));&/span&
&span class=&nv&&$cover&/span& &span class=&o&&=&/span& &span class=&nb&&str_replace&/span&&span class=&p&&(&/span&&span class=&s2&&&&/span&&span class=&se&&\\&/span&&span class=&s2&&&&/span&&span class=&p&&,&/span&&span class=&s2&&&&&/span&&span class=&p&&,&/span&&span class=&nb&&htmlspecialchars_decode&/span&&span class=&p&&(&/span&&span class=&nv&&$vv&/span&&span class=&p&&[&/span&&span class=&s1&&'cover'&/span&&span class=&p&&]));&/span&&span class=&c1&&//封面图片&/span&
&span class=&c1&&//现在存入数据库&/span&
&span class=&k&&echo&/span& &span class=&s2&&&标题:&&/span&&span class=&o&&.&/span&&span class=&nv&&$title&/span&&span class=&o&&.&/span&&span class=&nv&&$lastId&/span&&span class=&o&&.&/span&&span class=&s2&&&&/span&&span class=&se&&\n&/span&&span class=&s2&&&&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&cp&&?&&/span&&span class=&x&&&/span&
&/code&&/pre&&/div&&p&再次强调代码只是原理,其中一部分注视的代码要自己编写。&/p&&p&2、getMsgExt.php获取文章阅读量和点赞量的程序&/p&&div class=&highlight&&&pre&&code class=&language-php&&&span&&/span&&span class=&cp&&&?&/span&
&span class=&nv&&$str&/span& &span class=&o&&=&/span& &span class=&nv&&$_POST&/span&&span class=&p&&[&/span&&span class=&s1&&'str'&/span&&span class=&p&&];&/span&
&span class=&nv&&$url&/span& &span class=&o&&=&/span& &span class=&nv&&$_POST&/span&&span class=&p&&[&/span&&span class=&s1&&'url'&/span&&span class=&p&&];&/span&&span class=&c1&&//先获取到两个POST变量&/span&
&span class=&c1&&//先针对url参数进行操作&/span&
&span class=&nb&&parse_str&/span&&span class=&p&&(&/span&&span class=&nb&&parse_url&/span&&span class=&p&&(&/span&&span class=&nb&&htmlspecialchars_decode&/span&&span class=&p&&(&/span&&span class=&nb&&urldecode&/span&&span class=&p&&(&/span&&span class=&nv&&$url&/span&&span class=&p&&)),&/span&&span class=&nx&&PHP_URL_QUERY&/span& &span class=&p&&),&/span&&span class=&nv&&$query&/span&&span class=&p&&);&/span&&span class=&c1&&//解析url地址&/span&
&span class=&nv&&$biz&/span& &span class=&o&&=&/span& &span class=&nv&&$query&/span&&span class=&p&&[&/span&&span class=&s1&&'__biz'&/span&&span class=&p&&];&/span&&span class=&c1&&//得到公众号的biz&/span&
&span class=&nv&&$sn&/span& &span class=&o&&=&/span& &span class=&nv&&$query&/span&&span class=&p&&[&/span&&span class=&s1&&'sn'&/span&&span class=&p&&];&/span&
&span class=&c1&&//再解析str变量&/span&
&span class=&nv&&$json&/span& &span class=&o&&=&/span& &span class=&nb&&json_decode&/span&&span class=&p&&(&/span&&span class=&nv&&$str&/span&&span class=&p&&,&/span&&span class=&k&&true&/span&&span class=&p&&);&/span&&span class=&c1&&//进行json_decode&/span&
&span class=&c1&&//$sql = &select * from `文章表` where `biz`='&.$biz.&' and `content_url` like '%&.$sn.&%'& limit 0,1;&/span&
&span class=&c1&&//根据biz和sn找到对应的文章&/span&
&span class=&nv&&$read_num&/span& &span class=&o&&=&/span& &span class=&nv&&$json&/span&&span class=&p&&[&/span&&span class=&s1&&'appmsgstat'&/span&&span class=&p&&][&/span&&span class=&s1&&'read_num'&/span&&span class=&p&&];&/span&&span class=&c1&&//阅读量&/span&
&span class=&nv&&$like_num&/span& &span class=&o&&=&/span& &span class=&nv&&$json&/span&&span class=&p&&[&/span&&span class=&s1&&'appmsgstat'&/span&&span class=&p&&][&/span&&span class=&s1&&'like_num'&/span&&span class=&p&&];&/span&&span class=&c1&&//点赞量&/span&
&span class=&c1&&//在这里同样根据sn在采集队列表中删除对应的文章,代表这篇文章可以移出采集队列了&/span&
&span class=&c1&&//$sql = &delete from `队列表` where `content_url` like '%&.$sn.&%'& &/span&
&span class=&c1&&//然后将阅读量和点赞量更新到文章表中。&/span&
&span class=&k&&exit&/span&&span class=&p&&(&/span&&span class=&nb&&json_encode&/span&&span class=&p&&(&/span&&span class=&nv&&$msg&/span&&span class=&p&&));&/span&&span class=&c1&&//可以显示在anyproxy的终端里&/span&
&span class=&cp&&?&&/span&&span class=&x&&&/span&
&/code&&/pre&&/div&&p&3、getWxHis.php、getWxPost.php两个程序比较类似,一起介绍&/p&&p&==========日更新==========&/p&&p&因为出现了两种页面表现形式,拼接历史消息页面的地址也应该发生改变,但是目前实测,即使微信客户端出现的是第二种页面表现形式,也可以将第一种页面的链接地址发送给微信,同样有效。&/p&&div class=&highlight&&&pre&&code class=&language-php&&&span&&/span&&span class=&cp&&&?&/span&
&span class=&c1&&//getWxHis.php 当前页面为公众号历史消息时,读取这个程序&/span&
&span class=&c1&&//在采集队列表中有一个load字段,当值等于1时代表正在被读取&/span&
&span class=&c1&&//首先删除采集队列表中load=1的行&/span&
&span class=&c1&&//然后从队列表中任意select一行&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&s1&&'队列表为空'&/span&&span class=&p&&){&/span&
&span class=&c1&&//队列表如果空了,就从存储公众号biz的表中取得一个biz,这里我在公众号表中设置了一个采集时间的time字段,按照正序排列之后,就得到时间戳最小的一个公众号记录,并取得它的biz&/span&
&span class=&nv&&$url&/span& &span class=&o&&=&/span& &span class=&s2&&&http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=&&/span&&span class=&o&&.&/span&&span class=&nv&&$biz&/span&&span class=&o&&.&/span&&span class=&s2&&&#wechat_webview_type=1&wechat_redirect&&/span&&span class=&p&&;&/span&&span class=&c1&&//拼接公众号历史消息url地址(第一种页面形式)&/span&
&span class=&nv&&$url&/span& &span class=&o&&=&/span& &span class=&s2&&&https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=&&/span&&span class=&o&&.&/span&&span class=&nv&&$biz&/span&&span class=&o&&.&/span&&span class=&s2&&&&scene=124#wechat_redirect&&/span&&span class=&p&&;&/span&&span class=&c1&&//拼接公众号历史消息url地址(第二种页面形式)&/span&
&span class=&c1&&//更新刚才提到的公众号表中的采集时间time字段为当前时间戳。&/span&
&span class=&p&&}&/span&&span class=&k&&else&/span&&span class=&p&&{&/span&
&span class=&c1&&//取得当前这一行的content_url字段&/span&
&span class=&nv&&$url&/span& &span class=&o&&=&/span& &span class=&nv&&$content_url&/span&&span class=&p&&;&/span&
&span class=&c1&&//将load字段update为1&/span&
&span class=&p&&}&/span&
&span class=&k&&echo&/span& &span class=&s2&&&&script&setTimeout(function(){window.location.href='&&/span&&span class=&o&&.&/span&&span class=&nv&&$url&/span&&span class=&o&&.&/span&&span class=&s2&&&';},2000);&/script&&&/span&&span class=&p&&;&/span&&span class=&c1&&//将下一个将要跳转的$url变成js脚本,由anyproxy注入到微信页面中。&/span&
&span class=&cp&&?&&/span&&span class=&x&&&/span&
&/code&&/pre&&/div&&div class=&highlight&&&pre&&code class=&language-php&&&span&&/span&&span class=&cp&&&?&/span&
&span class=&c1&&//getWxPost.php 当前页面为公众号文章页面时,读取这个程序&/span&
&span class=&c1&&//首先删除采集队列表中load=1的行&/span&
&span class=&c1&&//然后从队列表中按照“order by id asc”选择多行(注意这一行和上面的程序不一样)&/span&
&span class=&k&&if&/span&&span class=&p&&(&/span&&span class=&o&&!&/span&&span class=&k&&empty&/span&&span class=&p&&(&/span&&span class=&s1&&'队列表'&/span&&span class=&p&&)&/span& &span class=&o&&&&&/span& &span class=&nb&&count&/span&&span class=&p&&(&/span&&span class=&s1&&'队列表中的行数'&/span&&span class=&p&&)&/span&&span class=&o&&&&/span&&span class=&mi&&1&/span&&span cl

我要回帖

更多关于 页面加载时触发的事件 的文章

 

随机推荐