本文最后更新于 2480 天前,其中的信息可能已经有所发展或是发生改变。
其实这个想法在初中的时候就有了,当时因为什么都不会,所以也没有去做这个东西
昨天下午十分无聊,突然想起来了这件事,便打开vs写了一波
0x00、基本原理:
这个东西是利用3gqq来实现的,3gqq几乎都是纯文本,也方便进行封装来实现功能
在几年前,3gqq是使用sid来存储用户的登陆信息的,但是我昨天测试了一下,现在已经改为用cookie来保存登陆信息(虽然在网址里也保存了sid参数)
打开http://pet.3g.qq.com/后的界面:
我们可以很轻松地找到真正用来存储登陆信息的两个cookie值,后面的测试也证实了这一点:
我们记下这个uin和skey的值,在后面会经常用到
0x01、构造http请求函数:
我们可以根据上面来编写获取信息的方法:
/// <summary> /// GET 请求与获取结果 /// </summary> public static string HttpGetPet(string Url, string postDataStr, string uin, string skey) { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); request.Method = "GET"; request.ContentType = "text/html;charset=UTF-8"; request.Headers.Add("cookie", "uin=" + uin + "; skey=" + skey); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; } catch { } return ""; }
可以看到参数里有uin和skey的值,我们可以测试一下:
string html = HttpGetPet("http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet", "", "你的uin", "你的skey"); Console.WriteLine(html); Console.ReadLine();
获取结果:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"> <wml> <head> <meta http-equiv="cache-control" content="no-cache"/> </head> <card id="mainid" title="手机QQ宠物" ontimer="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=1"> <timer value="9000"/> <p><a href="http://app.z.qq.com/app_list.jsp?B_UID=&">应用</a>>手机QQ宠物</p> <p>状态 | <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=2">资料</a> | <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=3">喂养</a> | <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=4">粉钻特权</a></p> <p> </p> <p> <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=30&gift=0">我的礼包</a> <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/invite?&petid=281914025101042&g_f=0">好友邀请</a> </p> <p> <img src="http://img.pet.qq.com/phone_pet/img/index12.gif" alt="QQ宠物"/> </p> <p> 我不是一个人看书,旅行,吃饭,因为有晨旭的陪伴! </p> <p> 昵称:pet <img src="http://img.pet.qq.com/phone_pet/LV1_0.gif" alt="VIP"/> <a href="http://sqq.3g.qq.com/s?aid=bizp&pt=page&pc=qzonepetvip&sid=%s"><img src="http://img.pet.qq.com/phone_pet/sq/L1_0.gif" alt="SUPERQ"/></a><br/> QQ号:961726194 <br/> 等级:47<br/> 状态:空闲 </p> <p> <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=24">宠 物日志</a> </p> <p> 成长值:926418/955400<br/> 饥饿值:3570/6000 <br/> 清洁值:3616/6000 <br/> 健康值:5/5 <br/> 心情:1000/1000 兴奋<br/> 成长速度: 260/小时 <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=4">粉钻可加速</a><br/> 刷新时间(分钟):<input type="text" size="2" maxlength="2" format="*N" value="15" name="curtime"/> <anchor> 确定 <go href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=1" method="post"> <postfield name="freshtime" value="$curtime"/> </go> </anchor> <anchor> 刷新 <go href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=1" method="post"> <postfield name="freshtime" value="$curtime"/> </go> </anchor> </p> <p><a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=5">学习</a> | <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=6">打工</a> | <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet?&petid=281914025101042&g_f=0&cmd=7">旅游</a> | <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/farm?&petid=281914025101042&g_f=0&cmd=10">农场</a> | <a href="http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/fish?&petid=281914025101042&g_f=0&cmd=11">渔场</a> | <a href="http://dld.qzapp.z.qq.com/qpet/cgi-bin/phonepk?cmd=index&&zapp_uin=961726194&from=qqpet">大乐斗</a> | <a href="http://pet.gamebbs.qq.com/forum.php?&">论坛</a> </p> <p> <a href="http://info60.z.qq.com/infocenter_v2.jsp?B_UID=0">个人中心</a>-<a href="http://blog60.z.qq.com/setting/console.jsp">设置</a>-<a href="http://blog60.z.qq.com/feedback/index.jsp">反馈</a>-<a href="http://blog60.z.qq.com/logout.jsp">退出</a><br/><a href="http://info.3g.qq.com/g/s?aid=index&KqqWap_Act=6&g_f=591&g_ut=1">手机腾讯网</a>-<a href="http://info.3g.qq.com/g/s?aid=navigation&KqqWap_Act=6&g_f=592&g_ut=1">导航</a>-<a href="http://wap.soso.com/navi.jsp?g_f=2119&g_ut=2">搜索</a><br/>我的<a href="http://house60.3g.qq.com/g/s?aid=home_self&KqqWap_Act=6&g_f=595&g_ut=1">家园</a>.<a href="http://f.qq.com/index.php?mod=login&act=qzone&qq=0&&g_f=2455">朋友</a>.<a href="http://ti50.3g.qq.com/g/s?g_f=2507&aid=h&&g_ut=1">微博</a><br/>小Q报时(18:47)<br/> </p> </card> </wml>
如果获取到了正确信息,向上面那样,说明试验成功
0x02、把正则封装好:
根据我的习惯,因为我没有用过dom树解析,所以我在这里用的是正则,封装的函数如下:
/// <summary> /// 直接获取正则表达式的最后一组匹配值 /// </summary> /// <param name="str"></param> /// <param name="regstr"></param> /// <param name="name"></param> /// <returns></returns> public static string Reg_get(string str, string regstr, string name) { string result = ""; MatchCollection matchs = Reg_solve(str, regstr); foreach (Match item in matchs) { if (item.Success) { result = item.Groups[name].Value; } } return result; } public static MatchCollection Reg_solve(string str, string regstr) { Regex reg = new Regex(regstr, RegexOptions.IgnoreCase); return reg.Matches(str); }
0x03、获取&返回信息:
因为我是放到qq机器人上面用的,所以先设置好统一回复语句:
public static string pleaseLogin = "请设置登陆信息!"; public static string petMore = "更多宠物命令请回复“宠物助手”";
获取基本信息的方法如下:
/// <summary> /// 获取宠物基本信息 /// </summary> /// <param name="uin"></param> /// <param name="skey"></param> /// <returns></returns> public static string GetPetState(string uin, string skey) { string result = ""; string html = HttpGetPet("http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet", "", uin, skey); html = html.Replace("\r", ""); html = html.Replace("\n", ""); if (html.IndexOf("手机统一登录") != -1) return pleaseLogin; result += Reg_get(html, "alt=\"QQ宠物\"/></p><p>(?<say>.*?)<", "say").Replace(" ", "") + "\r\n" + "宠物名:" + Reg_get(html, "昵称:(?<level>.*?)<", "level").Replace(" ", "") + "\r\n" + "等级:" + Reg_get(html, "等级:(?<level>.*?)<", "level").Replace(" ", "") + "\r\n" + "状态:" + Reg_get(html, "状态:(?<now>.*?)<", "now").Replace(" ", "") + "\r\n" + "成长值:" + Reg_get(html, "成长值:(?<now>.*?)<", "now").Replace(" ", "") + "\r\n" + "饥饿值:" + Reg_get(html, "饥饿值:(?<now>.*?)<", "now").Replace(" ", "") + "\r\n" + "清洁值:" + Reg_get(html, "清洁值:(?<now>.*?)<", "now").Replace(" ", "") + "\r\n" + "心情:" + Reg_get(html, "心情:(?<now>.*?)<", "now").Replace(" ", "") + "\r\n" + petMore; return result; }
列出宠物喂养物品:
/// <summary> /// 喂养宠物选择页面 /// </summary> /// <param name="uin"></param> /// <param name="skey"></param> /// <returns></returns> public static string FeedPetSelect(string uin, string skey,string page) { string result = ""; string html = HttpGetPet("http://qqpet.wapsns.3g.qq.com/qqpet/fcgi-bin/phone_pet", "cmd=3&page=" + page, uin, skey); html = html.Replace("\r", ""); html = html.Replace("\n", ""); if (html.IndexOf("手机统一登录") != -1) return pleaseLogin; result += "我的账户:" + Reg_get(html, "我的账户:(?<name>.*?)<", "name").Replace(" ", "") + "\r\n"; int i = 0; MatchCollection matchs = Reg_solve(Reg_get(html, "元宝(?<name>.*?)上页", "name").Replace(" ", ""), "<p>(?<name>.*?)<br"); string[] name = new string[matchs.Count]; string[] id = new string[matchs.Count]; foreach (Match item in matchs) { if (item.Success) { name[i++] += item.Groups["name"].Value; } } i = 0; matchs = Reg_solve(Reg_get(html, "元宝(?<name>.*?)上页", "name").Replace(" ", ""), "goodid=(?<id>.*?)\""); foreach (Match item in matchs) { if (item.Success) { id[i++] += "物品id:" + item.Groups["id"].Value; } } for(int j = 0; j < i;j++) { result += name[j] + "\r\n" + id[j] + "\r\n"; } if(Reg_get(html, "上页</a>(?<name>.*?)/", "name").Replace(" ", "") != "") { result += "第" + Reg_get(html, "上页</a>(?<name>.*?)/", "name").Replace(" ", "") + "页,共" + Reg_get(html, "上页</a>(.*?)/(?<name>\\d+)", "name").Replace(" ", "") + "页" + "\r\n"; } else { result += "第" + Reg_get(html, "上页(?<name>.*?)/", "name").Replace(" ", "") + "页,共" + Reg_get(html, "上页(.*?)/(?<name>\\d+)", "name").Replace(" ", "") + "页" + "\r\n"; } return result + petMore; }
基本就是这些了,再贴代码的话,这篇文章的字数就超过最大字数限制了
所有代码都在此处:
https://gist.github.com/chenxuuu/d9d682b58a40ead00250c00c43f1a7f3
欢迎各位大佬进行二次开发,如果开发出来了成果,请在此处留言,谢谢!