先上段废话:
不懂股票,前段时间看老爷子摘抄股票数据实在辛苦,于是写了个程序自己去大智慧服务器拿数据,拿来以后自己再组织下。
进入正题:
1.自己抓包分析大智慧登录,下载数据的指令。
2.然后写个简单Socket客户端
写的仓促,基本能完成工作。
 
 
登录:
 
//--------------------登录------------------------------------------------------
procedure TfrmCWMain.btnLoginClick(Sender: TObject);
var
    LLoginCmd:TBytes;
begin
    pubLogonTick:=GetTickCount;
    SetLength(LLoginCmd,28);
    Move(LoginCMd[0],LLoginCmd[0],28);
    self.ClientSocket1.Socket.SendBuf(LLoginCmd[0],28);
    Sleep(100);
    Application.ProcessMessages ;

    SetLength(LLoginCmd,0);
    SetLength(LLoginCmd,74);
    Move(LoginCmd1[0],LLoginCmd[0],74);
    self.ClientSocket1.Socket.SendBuf(LLoginCmd[0],74);
    LastLoginState:=LoginIngState;
    Application.ProcessMessages ;
end;
 
上面用到的LoginCMD,
指令为:
Const
    LoginCMD :Array[0..27] of Byte =($4C,$4F,$4E,$47,$41,$43,$43,$4F,$55,$4E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00);
    
向服务器发送完毕LoginCMD后,接着再发送发送指令
LoginCmd1:Array[0..73] of byte =($67,$77,$74,$65,$73,$74,$00,$00,$00,$00,
                                                        $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
                                                            $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
                                                            $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
                                                            $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
                                                            $4F,$5E,$5A,$4A,$57,$57,$E2,$E1,$E0,$DF,
                                                            $DE,$DD,$DC,$DB,$DA,$D9,$D8,$D7,$D6,$D5,
                                                            $27,$02,$00,$00);
这样就完成登录的命令。
 
登录完毕后,服务器开始返回N条数据。可以理解为无用。
 
接着开始获取财务透视数据
我的设计是可以一次性获取N支股票的数据。
单个股票的财务透视数据获取
//深市的
function GetSCwtsData(StrA:String;Socket:TClientWinSocket):integer;
var
    LLoginCmd:TBytes;
    Heard1,Heard2,Heard3:TBytes;
    j,I,K,l:integer;
begin
        DownGpTick:=GetTickCount;
        LastLoginState := DownCWTSDataState;
        SetLength(Heard1,0);
        SetLength(Heard1,14);
        for i:=Low(CWTSHeard1) to High(CWTSHeard1) do
        begin
            Heard1[i]:=CWTSHeard1[i];
        end;
        K:=i-1;
        for i:=1 to length(StrA) do
        begin
            Heard1[K+i]:=Byte(StrA[i]);
        end;
        K:=K+i;

        for l:=low(SCWTSEnd1) to High(SCWTSEnd1) do
        begin
            Heard1[k+l]:=SCWTSEnd1[l];
        end;
        SetLength(LLoginCmd,0);
        SetLength(LLoginCmd,14);
        Move(Heard1[0],LLoginCmd[0],14);
        Socket.SendBuf(LLoginCmd[0],14);
        Application.ProcessMessages ;
        Sleep(10);
        {    
        }
        K:=0;
        SetLength(Heard3,0);
        SetLength(Heard3,16);
        for i:=Low(CWTSHeard3) to High(CWTSHeard3) do
        begin
            Heard3[i]:=CWTSHeard3[i];
        end;
        K:=i-1;
        for i:=1 to length(StrA) do
        begin
            Heard3[K+i]:=Byte(StrA[i]);
        end;
        K:=K+i;
        for l:=low(SCWTSEnd3) to High(SCWTSEnd3) do
        begin
            Heard3[k+l]:=SCWTSEnd3[l];
        end;
        SetLength(LLoginCmd,0);
        SetLength(LLoginCmd,16);
        Move(Heard3[0],LLoginCmd[0],16);
        Socket.SendBuf(LLoginCmd[0],16);
        Application.ProcessMessages ;
        Sleep(1000);
end;
//沪市的
function GetCwtsData(StrA:String;Socket:TClientWinSocket):integer;
var
    LLoginCmd:TBytes;
    Heard1,Heard2,Heard3:TBytes;
    j,I,K,l:integer;
begin
        DownGpTick:=GetTickCount;
        LastLoginState := DownCWTSDataState;
        SetLength(Heard1,0);
        SetLength(Heard1,14);
        for i:=Low(CWTSHeard1) to High(CWTSHeard1) do
        begin
            Heard1[i]:=CWTSHeard1[i];
        end;
        K:=i-1;
        for i:=1 to length(StrA) do
        begin
            Heard1[K+i]:=Byte(StrA[i]);
        end;
        K:=K+i;

        for l:=low(CWTSEnd1) to High(CWTSEnd1) do
        begin
            Heard1[k+l]:=CWTSEnd1[l];
        end;
        SetLength(LLoginCmd,0);
        SetLength(LLoginCmd,14);
        Move(Heard1[0],LLoginCmd[0],14);
        Socket.SendBuf(LLoginCmd[0],14);
        Application.ProcessMessages ;
        Sleep(10);
        { //先不下载 操盘必读 部分数据了.
        K:=0;
        SetLength(Heard2,0);
        SetLength(Heard2,16);
        for i:=Low(CWTSHeard2) to High(CWTSHeard2) do
        begin
            Heard2[i]:=CWTSHeard2[i];
        end;
        K:=i-1;
        for i:=1 to length(StrA) do
        begin
            Heard2[K+i]:=Byte(StrA[i]);
        end;
        K:=K+i;
        for l:=low(CWTSEnd2) to High(CWTSEnd2) do
        begin
            Heard2[k+l]:=CWTSEnd2[l];
        end;
        SetLength(LLoginCmd,0);
        SetLength(LLoginCmd,16);
        Move(Heard2[0],LLoginCmd[0],16);
        Socket.SendBuf(LLoginCmd[0],16);
        Application.ProcessMessages ;
        Sleep(300);
        }
        K:=0;
        SetLength(Heard3,0);
        SetLength(Heard3,16);
        for i:=Low(CWTSHeard3) to High(CWTSHeard3) do
        begin
            Heard3[i]:=CWTSHeard3[i];
        end;
        K:=i-1;
        for i:=1 to length(StrA) do
        begin
            Heard3[K+i]:=Byte(StrA[i]);
        end;
        K:=K+i;
        for l:=low(CWTSEnd3) to High(CWTSEnd3) do
        begin
            Heard3[k+l]:=CWTSEnd3[l];
        end;
        SetLength(LLoginCmd,0);
        SetLength(LLoginCmd,16);
        Move(Heard3[0],LLoginCmd[0],16);
        Socket.SendBuf(LLoginCmd[0],16);
        Application.ProcessMessages ;
        Sleep(1000);
end;
这里用的的指令:
    CWTSHeard1:Array[0..2] of Byte=($42,$00,$00);
    CWTSEnd1:Array[0..4]     of byte=($00,$03,$7E,$01,$00);
    SCWTSEnd1:Array[0..4]    of byte=($00,$03,$7E,$02,$00);

    CWTSHeard2:Array[0..2] of byte=($44,$00,$00);
    CWTSEnd2:Array[0..6]     of Byte=($00,$30,$30,$01,$00,$01,$00);
    SCWTSEnd2:Array[0..6]    of Byte=($00,$30,$30,$02,$00,$02,$00);

    CWTSCmd1:Array[0..2] of Byte=($6E,$00,$00);

    CWTSHeard3:Array[0..2] of Byte = ($44,$00,$00);
    CWTSEnd3:Array[0..6] of Byte = ($00,$00,$00,$01,$00,$02,$00);
    SCWTSEnd3:Array[0..6] of byte= ($00,$00,$00,$02,$00,$02,$00);
 
好,下载也完成了。
接下来开始接收了:
procedure TfrmCWMain.ClientSocket1Read(Sender: TObject;
    Socket: TCustomWinSocket);
var
    rLen:Integer;
    buf:PAnsiChar;
    bufLen:Integer;
    mFile:TMemoryStream;
    GPCode:String;
begin
    inc(P_BackNum);
    memo1.Lines.Add('----------------------');
    rLen:=Socket.ReceiveLength ;
    getMem(buf,rLen);
    try
    bufLen := Socket.ReceiveBuf(buf^,rLen);
    memo1.Lines.Add(inttostr(buflen));
    memo1.lines.add(buf);
    {if (LastLoginState=LoginIngState) and (bufLen=152) then
    begin
        inc(P_152LenNum);
        if P_152LenNum=3 then
        begin
            SendLoginCmd3;
            TimerLogin2.Enabled := True;
        end;
    end;
    }
    if (LastLoginState = DownCWTSDataState) and (P_BackNum>0) then
    begin
        mFile := TMemoryStream.Create ;
        mFile.WriteBuffer(buf^,rLen);
        mFile.Position := 0;
        if isNewGPData(mFile,GPCode) then
        begin
            pubDownGPCodeList.Add(GPCode);
            mFile.Position := 0;
            InputDBStreamEx(mFile,GPCode);
        end
        else
        begin
            mFile.Position := 0;
            InputDBStream(mFile,pubDownGPCodeList.Strings[pubDownGPCodeList.count -1]);
        end;

        //mFile.Position := 0;
        //mFile.SaveToFile(format('E:\DzhFiles\%d.txt',[p_BackNum]));
        mfile.Free;
    end;
    if (LastLoginState=LoginIngState) and (P_BackNum=1) then
    begin
        SendLoginCmd2_1;
    end;
    //LoginCmd3
    finally
        Freemem(buf,rLen);
    end;
end;
界面: