不想看太多前情提要废话的,可以往下拉,第一张图片之后,开始讲技术正题——

故事开始,作为一个穷人呢,也要理财的,毕竟,哪怕是买点四大行的股票,也比直接存在银行来得划算呐~
虽然券商提供了很多渠道,比如我用的是招商证券的户,有微信渠道、有官方一户通APP、有PC端、有网页端……
但是,微信太臃肿,官方APP老是搞升级烦,PC端花里胡哨爱弹提示消息(时不时也提升级),网页端则一小会不操作就被踢下线得重新登陆,而且登陆需要短信验证、偏偏每天的短信验证数量是有上限的……
嗯,其实重新登陆这个问题APP和PC客户端也一样有,只不过网页版的更烦,虽然知道是为了安全考虑,但是,不爽啊……
于是乎,决定自己动手来搞定需求吧!
给我这个念头的,其实是上次跟我提SOCKIT的那位大佬,大佬表示这东西用得好,可以玩出各种花来
仔细想想,要做就做到底,早就看那些指数烦了,定制一套自己的数据和交易系统
千里之行,始于足下,首先,从搞定基本的界面、登陆、保持在线、以及最核心的订单处理功能开始。
这次用的是winform界面,虽然上次玩C#已经是去年年初的事情了,有点手生,但不得不说,正是因为手生,才显得VS的友好,太容易上手了!
以下是初步的半成品界面,也就是搭了个拙劣框架的样子——

中间那一大块的图表和数据处理功能其实还没做(三天打鱼、两天晒网的犯拖延病,还有犹豫症,也不知道啥时候能做好,明明是挺简单的……)
当然了,发这篇文自然不是为了晒张图,写这么多废话还没上代码,只是因为思考了一下,觉得意义不大,因为未必用的一个证券商的户
这里主要是说说思路,然后再夹杂一点细节——
正题开始了!
点一:操作账户,总要有个接口吧
抓包解析PC端、APP端接口之类的,对于我这种新手来讲,也太过扯淡了,网页版才是最优选项
原本我是想直接用http组件完成所有交互的,但是,比起分析那些杂乱的JS的请求与返回、编写又臭又长的处理代码,还是用webbrowser吧,调试也方面得多
Chrome打开券商官网,进入交易通道,从登陆界面开始按下F12,查找表单控件……
验证码图片套到界面上这一点,我是抄的代码:

HtmlElementCollection peg = webBrowser1.Document.GetElementsByTagName("img");HTMLDocument doc = (HTMLDocument)webBrowser1.Document.DomDocument;HTMLBody body = (HTMLBody)doc.body;IHTMLControlRange rang = (IHTMLControlRange)body.createControlRange();IHTMLControlElement Img = (IHTMLControlElement)peg[1].DomElement; //图片地址Image oldImage = Clipboard.GetImage();rang.add(Img);rang.execCommand("Copy", false, null);  //拷贝到内存Image numImage = Clipboard.GetImage();try{Clipboard.SetImage(oldImage);}catch { }pictureBox1.Image = numImage;

在登陆按钮的点击事件里,把下面的模拟输入代码循环一下,填入表单,再模拟点下网页上的登陆按钮,就可以获取完整COOKIE,从而使用http组件进行各种POST提交和请求数据了

private void setinput(int index,string str){HtmlElementCollection hec = webBrowser1.Document.Body.GetElementsByTagName("input");Console.WriteLine(hec.Count);hec[index].Focus();hec[index].InnerText = "";for (int i = 0; i < str.Length; i++)//把char数组一个个通过sendkes输入{SendKeys.Send(str[i].ToString());SendKeys.Flush();}hec[index].RemoveFocus();}

点二:关于cookie
别的券商如何不清楚,但招商的这个cookie里,有一个token令牌,提交POST的时候,是必须的,在且只有在提交交易的时候,会进行更新,其他的网页刷新、查询、撤单操作,都不会触发
当然,其他的COOKIE也是必须的,虽然并不会频繁更新变动,但是,直接用webbrowser自带的方法去获取,获取不到完整的cookie,至少我是没成功,如果有大佬能做到的话,请不吝赐教!
这里我用的也是抄来的代码,验证直抄可用

[System.Runtime.InteropServices.DllImport("wininet.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]static extern bool InternetGetCookieEx(string pchURL, string pchCookieName, StringBuilder pchCookieData, ref System.UInt32 pcchCookieData, int dwFlags, IntPtr lpReserved);public static string GetCookieString(string url){// Determine the size of the cookie      uint datasize = 256;StringBuilder cookieData = new StringBuilder((int)datasize);if (!InternetGetCookieEx(url, null, cookieData, ref datasize, 0x00002000, IntPtr.Zero)){if (datasize < 0)return null;// Allocate stringbuilder large enough to hold the cookie    cookieData = new StringBuilder((int)datasize);if (!InternetGetCookieEx(url, null, cookieData, ref datasize, 0x00002000, IntPtr.Zero))return null;}return cookieData.ToString();}

点三:关于上面说的TOKEN更新
一开始我是眼瞎了,各种瞎搜索关于token的资料,然后无意间又看了一眼我保存下来的请求信息,才发觉更新的TOKEN就藏在Header里…
怪自己想得太复杂…
于是,最核心的代码之一,就完成了:

             cookie = GetCookieString(webBrowser1.Url.ToString());Console.WriteLine(cookie);string[] cokies = cookie.Split(' ');Dictionary<string, string> cookies = new Dictionary<string, string>();for (int i = 0; i < cokies.Length; i++){if (cokies[i].Contains('='))cookies.Add(cokies[i].Split('=')[0], cokies[i].Split('=')[1].Trim(new char[2] { '\"', ';' }));}
//以上是获取完整的cookie并处理相应字段信息,下面才是post请求Encoding myEncoding = Encoding.GetEncoding("gb2312");  //选择编码字符集string jytoken = cookies["cms_token"];string data = "jytoken=" + jytoken + "这里涉及一点个人数据,就不贴了,反正后面是要调整的,现在只是作为展示";  //要上传到网页系统里的数据(字段名=数值 ,用&符号连接起来),其实就是form单,如果是请求信息而非提交数据(看相应的JS里有没有form单就是了),可以置空为""byte[] bytesToPost = System.Text.Encoding.Default.GetBytes(data); //转换为bytes数据string responseResult = String.Empty;HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("地址就是查看到的相关请求Header里开头的reques地址");   //创建一个有效的httprequest请求ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;req.Method = "POST";req.Headers.Add("Cookie", cookie);req.ContentType ="application/x-www-form-urlencoded;charset=gb2312";req.ContentLength = bytesToPost.Length;try{using (System.IO.Stream reqStream = req.GetRequestStream()){reqStream.Write(bytesToPost, 0, bytesToPost.Length);     //把要上传网页系统的数据通过post发送}}catch{MessageBox.Show("表单提交出错了!");return;}HttpWebResponse cnblogsRespone = (HttpWebResponse)req.GetResponse();if (cnblogsRespone != null && cnblogsRespone.StatusCode == HttpStatusCode.OK){System.IO.StreamReader sr;using (sr = new System.IO.StreamReader(cnblogsRespone.GetResponseStream())){responseResult = sr.ReadToEnd();  //网页系统的json格式的返回值,在responseResult里Console.WriteLine("返回值:" + responseResult.ToString());if (responseResult.ToString().Contains("true")){WebHeaderCollection hd = cnblogsRespone.Headers;string[] ks = hd.AllKeys;foreach (string i in ks){Console.WriteLine(i);}string rcokie = cnblogsRespone.GetResponseHeader("Set-Cookie");//没错,这里就是我找到的券商返回的新令牌所在字段,下面则简单的拆解获取Console.WriteLine(rcokie);string[] strcokie = rcokie.Split(',');string ncokie = webBrowser1.Document.Cookie;foreach (string i in strcokie){if (i.Contains("cms_token"))ncokie = i.Split(';')[0];}webBrowser1.Document.Cookie = ncokie;//实际上完整的cookie信息有几个字段,看上面开头的处理代码就知道了,但webbrowser控件里get到的cookie只有token这一段,所以我也只更新这一段进去}}sr.Close();}elseConsole.WriteLine("网页错误代码:" + cnblogsRespone.StatusCode);cnblogsRespone.Close();

以上这段代码,在GetResponse的部分稍作变更,就可以套成各种查询处理了,到这里,交易操作、查询操作、相应的股票信息等等,券商提供的基本功能交互,都有了
只要循环对webbrowser控件执行一下刷新,就应该能保持一直在线,避免反复登陆了
但是呢,如果只是这样的话,未免也太没意思了
考虑到之前做的sockit通讯确实挺有意思的,我又写了个python爬虫,爬了一下俩交易所的股票列表
敲了一段c代码,从另外一个股票信息商品获取信息,把它再扩展一下,结合数据库,打包成dll,就可以做一套自己的数据分析系统
在数据分析的基础上,再做一个自动交易功能
计划是这样,基本上也是临门一脚,差点细节和时间功夫
然而拖延病、犹豫症……
啥时候完成第二期测试,再发个篇二出来吧

小散户给自己写一个交易软件-篇(1)相关推荐

  1. 用小程序云开发写一个多人记账小程序

    应女朋友要求,用小程序云开发写一个记账小程序,适合情人记账.家庭记账.团队记账.多人记账的小程序 先上成品图吧 主页: 记账页: 详情页: 个人中心页: 统计页: 其余的页面就不一一展示了,使用到的主 ...

  2. python编程小游戏-使用Python写一个小游戏

    引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下 ...

  3. 微信小程序入坑: 写一个简化版知乎日报

    最近开始入坑微信小程序,发现想要练手也不容易,找免费的基于HTTPS的API就要花点时间.在看了网上一些介绍后,决定采用知乎日报的API,写一个简单版的知乎日报作为入坑练习.本文尝试使用微信小程序写一 ...

  4. java连连看小程序,用JS写一个连连看小程序

    思路 决定内容区域的大小和图片种类数量 图片应该放多少行,多少列.必须是偶数 整个区域应该是在图片外多围上一圈,也就是行数和列数都应该比图片的多1 放多少对图片,一对两张.注意对数不能超过所有图片总数 ...

  5. python写一个服务_写一个Python的windows服务

    1. 安装pywin32和pyinstaller pip install pywin32 pip install pyinstaller 2.写一个服务Demo # -*- coding: utf-8 ...

  6. python写游戏脚本-使用Python写一个小游戏

    引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规的项目开发流程,手把手教大家写个python小游戏,来感受下 ...

  7. python软件代码示例-用Python写一个模拟qq聊天小程序的代码实例

    Python 超简单的聊天程序 客户端: import socket, sys host = '10.248.27.23' # host = raw_input("Plz imput des ...

  8. 使用C语言写一个扫雷小游戏

    前言 相信扫雷游戏小伙伴们肯定都玩过吧,学习了C语言中的数组.函数等基础内容之后就可以自己写一个简易的扫雷小游戏了,今天就我写扫雷小游戏的过程及思路写一篇博客,希望大家看完我的博客能有所收获. 软件及 ...

  9. 利用 Python 写一个颜值测试小工具

    我们知道现在有一些利用照片来测试颜值的网站或软件,其实使用 Python 就可以实现这一功能,本文我们使用 Python 来写一个颜值测试小工具. 很多人学习python,不知道从何学起. 很多人学习 ...

最新文章

  1. echo向文件中写入
  2. 消除8个关于AI在商业中应用的错误观念
  3. Ubuntu下建立Pycharm快捷方式
  4. java servlet filter_Java Servlet Filter
  5. centos6.5 yum安装mysql_CentOS 6.5使用yum安装MySQL快速上手必备
  6. 云计算的新界面—Kubernetes容器技术
  7. 状态压缩:枚举子集(最优组队)(ybtoj)(动态规划)
  8. SpringCloud |第二篇: 服务消费者(Ribbon)
  9. Linux命令中正则表达式的运用
  10. python:第一个简单爬虫程序
  11. 王琪你计算机学院,计算机学院“计忆时光”2019元旦联欢会暨年度颁奖典礼圆满举行...
  12. 模式对话框与非模式对话框的创建方法
  13. 玩转混合云+边缘计算,且看ZStack Mini!
  14. 张宇高等数学强化阶段笔记并标记重点
  15. 河北联通烽火HG680-J机顶盒破解安装教程
  16. gateway中的局部过滤器_GateWay过滤器
  17. sending data 慢SQL原因排查命令
  18. 小白学习MySQL - MySQL会不会受到“高水位”的影响?
  19. c++ MFC 根据屏幕分辨率变化自动调整控件位置和大小
  20. arduino定时器函数如何使用_Arduino定时器配置(Timer0,Timer1,Timer2)

热门文章

  1. ISO1,ISO2,OSI,IOS
  2. 运动类计算公式----卡路里计算
  3. EXCEL-OR函数的使用方法
  4. 【SPFA,并查集,dp】黑心商店1
  5. 2013中国手机的春天在哪里?
  6. 仿微信页面——Android程序设计
  7. NID-00135: 存在 1 个活动的线程
  8. jQuery为table表格动态添加或删除tr
  9. (转)详解 Secure Boot 和 Winows 8 及 UEFI启动的关系
  10. Python视频剪辑AutoCut在文档中合成制作口播视频