从“什么值得买”抓取特价信息并发送至微信

来源:互联网 发布:如何避免网络陷阱 编辑:程序博客网 时间:2024/05/04 05:45

声明: 本博文和相关代码仅供个人学习使用。

需求

现在购物网站越来越多,优惠常常有,但是又不一定正好被你撞见,而且每天上网逛商城也挺浪费时间的。偶然看到优惠信息了吧,又已经过期或者被秒杀光了。所以我想做一个程序能够定时在网站上搜索相关产品的优惠信息,在抓到信息后第一时间通知自己。去所有电商网站抓取肯定不现实,最方便的做法就是直接去类似“什么值得买”或者”买个便宜货”这类的消息聚合网站上提取信息啦。

程序要做到的:

  • 定时抓取相关关键词的优惠信息
  • 发现新的优惠发送微信通知(这里使用微信企业号开发平台)
  • 已经发送过的信息不再发送第二次

首先先把最终效果展示一下 :

这里写图片描述

已经发送过的信息不会重复发送

这里写图片描述

微信会收到优惠信息的标题,发布时间以及连接地址,这样就可以直接在手机端打开查看了。

程序相关设计

模块设计

大致分为:HTTP处理、文件处理、微信接口三个部分。简要介绍一下,具体代码可以看附录的Github项目。

HTTP处理

需要实现项目如下:

  • 简单的http的GET\POST请求
  • 处理网页DOM文档,将优惠信息提取出来
  • 设计优惠信息的数据结构

具体代码不贴了,GET\POST代码网上一大堆。处理DOM文档主要用的jsoup,文档也是一大堆。优惠信息主要只记录标题、详情、日期、时间、URL连接这些内容。

文件处理

只要实现:将优惠信息的数据列表存成文件、从文件中读取数据列表即可。简单接口如下:

//读取public static List<FoundItem> read() throws FileNotFoundException, IOException;//写入public static void write(List<FoundItem> items) throws IOException;

微信

主要实现两个功能:获取token,发送信息。由于发送信息时候的url需要带上token,因此一个完整的发送消息过程应该以此调用上述两个过程的代码。
1、 获取token

//获取token用Http get即可,在地址中带上corpId, corpsecret字符串即可private String getUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid="+corpId+"&corpsecret="+corpsecret;//返回数据格式为json,其中access_token是我们需要的

2、 发送信息

API文档 - 消息类型及数据格式

//使用POST形式发送private static final String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=";//后边应该加上上边获得的access_token//post的json参数示意如下/*{   "touser": "UserID1|UserID2|UserID3",   "toparty": " PartyID1 | PartyID2 ",   "totag": " TagID1 | TagID2 ",   "msgtype": "text",   "agentid": 1,   "text": {       "content": "Holiday Request For Pony(http://xxxxx)"   },   "safe":"0"}*///返回数据格式也是json,如果errCode="0"即说明接口调用成功了

具体实现也是简单的IO操作,代码不具体贴出来了。

流程设计

首先程序外围由一个Timer定时触发程序。
每次触发流程:
1、 向目标网址”search.smzdm.com?c=xxx&s=xxx”获取信息
2、 jsoup处理并提取优惠信息List
3、 读取已经发送的优惠信息记录文件
4、 对比找到还未发送的文件,依次调用weixin接口发送消息
5、 把新发送的数据写入记录文件

附:项目

未解决的问题

上文实验通过浏览器获取cookie后手动处理Header才能获取页面文本。直接通过httpclient访问会返回HTTP 521错误。但该错误同时会返回一段代码

<script>var x="https@Apr@captcha@Path@location@String@window@challenge@06@cd@e@_phantom@a@4@match@Expires@setTimeout@try@length@16@x@join@return@substr@01@addEventListener@1459902268@cookie@Wed@h@24@f@__jsl_clearance@r@28@document@div@dc@i@href@innerHTML@reverse@function@charAt@1500@5@0@l@while@if@false@catch@eval@for@toLowerCase@createElement@firstChild@var@fromCharCode@GMT@replace@2@__phantomas@412@DOMContentLoaded@else@attachEvent@onreadystatechange".replace(/@*$/,"").split("@"),y="1r 1h=1c(){1i(7.c||7.21){};1r a,17='12=r.22|1g|';1r 11=[1c(l){n 1m('6.1s('+l+')')},(1c(){1r u=15.1p('16');u.1a='<d 19=\\'/\\'>l</d>';u=u.1q.19;1r 13=u.f(/1?:\\/\\//)[1g];u=u.o(13.j).1o();n 1c(l){1n(1r 18=1g;18<l.j;18++){l[18]=u.1d(l[18])};n l.m('')}})()];a=[[(-~!{}+[]+[])+(e+[])],[(-~!{}+[]+[])+(-~!{}+[]+[])+([-~!{}+20]*(-~!{}+20)+[[], !![]][~~{}]),[(-~{}|((+!![])<<(+!![])))]+[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])],(-~-~[]-~!{}-~-~[]+[])+[(+[])],[(+!![])-~-~[]-~!{}-~-~[]]+[(+!![])-~-~[]-~!{}-~-~[]],(-~!{}+[]+[])+[(+[])]+(-~-~[]-~!{}-~-~[]+[]),[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])]+[(+!![])-~-~[]-~!{}-~-~[]],(-~!{}+[]+[])+[(+[])]+(((+!![])<<(+!![]))+[[]][(+[])]),[(-~{}|((+!![])<<(+!![])))]+[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])],(-~-~[]-~!{}-~-~[]+[])+[(+[])],[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])]+[(+[])],[((+!![])<<(+!![]))-~[1f]]+(-~!{}+[]+[]),[(+!![])-~-~[]-~!{}-~-~[]]+[((+!![])<<(+!![]))-~[1f]],[((+!![])<<(+!![]))-~[1f]]+(-~!{}+[]+[]),(-~!{}+[]+[])+[(+[])]+[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])],(-~-~[]-~!{}-~-~[]+[])+[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])]],[(-~!{}+[]+[])+(e+[]),(-~!{}+[]+[])+[(+[])]],[[((+!![])<<(+!![]))-~[1f]]+[(-~{}|((+!![])<<(+!![])))],[(+!![])-~-~[]-~!{}-~-~[]]+[((+!![])<<(+!![]))-~[1f]],[((+!![])<<(+!![]))-~[1f]]+(e+[]),(-~!{}+[]+[])+[(+[])]+[(-~{}|((+!![])<<(+!![])))],[((+!![])<<(+!![]))-~[1f]]+[(+[])]],[(e+[])],[[((+!![])<<(+!![]))-~[1f]]+(((+!![])<<(+!![]))+[[]][(+[])])],[(-~!{}+[]+[])],[[(+!![])-~-~[]-~!{}-~-~[]]+[((+!![])<<(+!![]))-~[1f]],[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])]+[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])],(-~!{}+[]+[])+(-~!{}+[]+[])+[(-~{}|((+!![])<<(+!![])))],(-~!{}+[]+[])+[(+[])]+(((+!![])<<(+!![]))+[[]][(+[])]),[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])]+[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])],[(-~{}|((+!![])<<(+!![])))]+[-~~~![]-~~~![]-~((-~-~[])*[-~-~[]])],(-~-~[]-~!{}-~-~[]+[])+(-~!{}+[]+[]),[(+!![])-~-~[]-~!{}-~-~[]]+[((+!![])<<(+!![]))-~[1f]]]];1n(1r 18=1g;18<a.j;18++){a[18]=11.1b()[[(+[])]](a[18])};a=a.m('');17+=a;h('5.19=5.19.1u(/[\\?|&]3-8/,\\'\\')',1e);15.s=(17+';g=t, 9-2-k p:10:14 1t;4=/;');};1j((1c(){i{n !!7.q;}1l(b){n 1k;}})()){15.q('23',1h,1k);}24{15.25('26',1h);}",z=0,f=function(x,y){    var a=0,b=0,c=0;    y=y||99;    while((a=x.shift())&&(b=a.charCodeAt(0)-77.5))        c=(Math.abs(b)<13?(b+48.5):parseInt(a,36))+y*c;},g=y.match(/\b\w+\b/g).sort(function(x,y){return f(x)-f(y)}).pop();while(f(g,++z)-x.length){};eval(y.replace(/\b\w+\b/g, function(y){return x[f(y,z)-1]}));</script>

这段代码会在浏览器中增加cookie类似:

"__jsluid=866575b22f70d10e50d933c88f9d3411;__jsl_clearance=1459854000.308|0|bogaNWw49Alg1AzlYoj1FX2YNnA%3D;"

在下次http请求时候应该带上这个cookie才能正常获取到页面的信息。

如果能用java实现这段代码,并生成cookie就可以真正实现稳定抓取了。

参考资料

微信企业号申请以及应用设置

微信企业号API开发文档

项目代码

github - SMZDM-WATCHER

0 0
原创粉丝点击