读书人

qq邮箱自动登录解决方法

发布时间: 2012-03-25 20:55:16 作者: rapoo

qq邮箱自动登录
最近想写一个自动登录邮箱的程序,比如qq邮箱(https://mail.qq.com/cgi-bin/loginpage?flowid=186679953232973719)

一下子感觉无从下手,特别是怎么自动识别验证码,让人头大,求大神给个思路,最好能给出可用的代码,谢谢!

[解决办法]
先用图像算法对验证码进行去噪、分割、识别,获取验证码值,然后用webbrowser获取邮箱接口,提交账号、密码和验证码值即可。

下面的代码希望对你有用,GoodLuck!

C/C++ code
// IEDoingDlg.h : 头文件//#pragma once#include "explorer1.h"// 所以声明它是必须的#include <atlcom.h> #include <mshtmhst.h>#include <mshtml.h>// CIEDoingDlg 对话框class CIEDoingDlg : public CDialog{// 构造public:CIEDoingDlg(CWnd* pParent = NULL); // 标准构造函数// 对话框数据enum { IDD = IDD_IEDOING_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()public:CExplorer1 m_web;DECLARE_EVENTSINK_MAP()void DocumentCompleteExplorer1(LPDISPATCH pDisp, VARIANT* URL);//浏览器全部加载完全afx_msg void OnBnClickedOk();// 设置名字void OnSetName(void);void SetName(IHTMLDocument2 * pIHTMLDocument2);// 模拟输入密码void OnPass(void);void OnSetPass(IHTMLDocument2 * pIHTMLDocument2);// 点击按扭void OnClickRegBtn(IHTMLElementCollection * pElemColl, CString strElementId);// 类型转化VARIANT StringToVariant(CString str);// 认证码图片取得void OnGetCode(void);afx_msg void OnEnChangeEdit1();// 调用验证码输入void OnCode(void);// 传递验证码void OnSetPassCode(IHTMLDocument2 * pIHTMLDocument2);// 输入的验证码CString m_code;afx_msg void OnBnClickedButton1();};BOOL CIEDoingDlg::OnInitDialog(){CDialog::OnInitDialog();// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);   // 设置大图标SetIcon(m_hIcon, FALSE);  // 设置小图标// TODO: 在此添加额外的初始化代码    m_web.Navigate(_T("https://mail.qq.com/cgi-bin/loginpage?flowid=186679953232973719"),NULL,NULL,NULL,NULL);return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE}// 如果向对话框添加最小化按钮,则需要下面的代码//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,//  这将由框架自动完成。void CIEDoingDlg::OnPaint(){if (IsIconic()){  CPaintDC dc(this); // 用于绘制的设备上下文  SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);  // 使图标在工作区矩形中居中  int cxIcon = GetSystemMetrics(SM_CXICON);  int cyIcon = GetSystemMetrics(SM_CYICON);  CRect rect;  GetClientRect(&rect);  int x = (rect.Width() - cxIcon + 1) / 2;  int y = (rect.Height() - cyIcon + 1) / 2;  // 绘制图标  dc.DrawIcon(x, y, m_hIcon);}else{  CDialog::OnPaint();}}//当用户拖动最小化窗口时系统调用此函数取得光标//显示。HCURSOR CIEDoingDlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}BEGIN_EVENTSINK_MAP(CIEDoingDlg, CDialog)ON_EVENT(CIEDoingDlg, IDC_EXPLORER1, 259, CIEDoingDlg::DocumentCompleteExplorer1, VTS_DISPATCH VTS_PVARIANT)END_EVENTSINK_MAP()void CIEDoingDlg::DocumentCompleteExplorer1(LPDISPATCH pDisp, VARIANT* URL){// TODO: 在此处添加消息处理程序代码    CString strUrl;HRESULT hr;IUnknown*  pUnk;LPDISPATCH lpWBDisp;pUnk = m_web.GetControlUnknown();ASSERT(pUnk);hr = pUnk->QueryInterface(IID_IDispatch, (void**)&lpWBDisp);ASSERT(SUCCEEDED(hr));strUrl=URL->bstrVal;int iurl;   iurl=strUrl.Find(_T("cctrydefault"));if (iurl!=-1){  OnPass();  OnGetCode();}else{  if (pDisp == lpWBDisp){              OnSetName();}}}
[解决办法]
汗,内容过长,接着发。
C/C++ code
void CIEDoingDlg::OnBnClickedOk(){        // TODO: 在此添加控件通知处理程序代码        OnOK();}// 设置名字void CIEDoingDlg::OnSetName(void){::CoInitialize(NULL);        //初始化 COM 公寓CComQIPtr < IHTMLDocument2 > spDoc =m_web.get_Document();SetName(spDoc);::CoUninitialize();}//输入名字void CIEDoingDlg::SetName(IHTMLDocument2 * pIHTMLDocument2){if( !pIHTMLDocument2 )        {                return;        }        HRESULT hr;        CComBSTR bstrTitle;        pIHTMLDocument2->get_title( &bstrTitle );        //取得文档标题                CComQIPtr< IHTMLElementCollection > spElementCollection;        hr = pIHTMLDocument2->get_forms( &spElementCollection );        //取得表单集合        CComQIPtr< IHTMLElement > pIHTMLEle;        hr =pIHTMLDocument2->get_body(&pIHTMLEle);     //读取文档        if ( FAILED( hr ) )         {                return;        }        long nFormCount=0;                                //取得表单数目        hr = spElementCollection->get_length( &nFormCount );        if ( FAILED( hr ) )        {                return;        }        CString str;        for(long i=0; i<nFormCount; i++)        {                IDispatch *pDisp = NULL;        //取得第 i 项表单                hr = spElementCollection->item( CComVariant( i ), CComVariant(), &pDisp );                        if ( FAILED( hr ) )         continue;//表单是<input type="text" default_txt="QQ号或邮箱帐号" id="uin" name="uin" value="" tabindex="1" style="ime-mode: disabled;" class="text" />                        CComQIPtr< IHTMLFormElement > spFormElement = pDisp;                pDisp->Release();                long nElemCount=0;                        //取得表单中 域 的数目                hr = spFormElement->get_length( &nElemCount );                if ( FAILED( hr ) )                continue;                USES_CONVERSION;                for(long j=0; j<nElemCount; j++)                {                        CComDispatchDriver spInputElement;        //取得第 j 项表单域                        hr = spFormElement->item( CComVariant( j ), CComVariant(), &spInputElement );                        if ( FAILED( hr ) )        continue;//表单域是 type="text" default_txt="QQ号或邮箱帐号" id="uin" name="uin" value="" tabindex="1" style="ime-mode: disabled;" class="text"                          CComVariant vID, vType;                        hr = spInputElement.GetPropertyByName( L"id", &vID );                           if( FAILED( hr ) )        continue;                        hr = spInputElement.GetPropertyByName( L"type", &vType );                        if( FAILED( hr ) )        continue;                        LPCTSTR lpVID  = vID.bstrVal ?                                OLE2CT( vID.bstrVal  ) : _T("NULL");                        LPCTSTR lpType = vType.bstrVal ?                                OLE2CT( vType.bstrVal ) : _T("NULL");                        CString strID(lpVID), strType(lpType);                        if (strID.CompareNoCase(_T("uin")) == 0 && strType.CompareNoCase(_T("text")) == 0){                                //是邮箱编辑框                                CComVariant   vSetValue(_T("cctrydefault"));                                spInputElement.PutPropertyByName(L"value", &vSetValue );     //填写表单域                        }                        spFormElement->submit();//刷新窗体                }                 pDisp->Release();        }}// 模拟输入密码void CIEDoingDlg::OnPass(void){        ::CoInitialize(NULL);        //初始化 COM 公寓        CComQIPtr < IHTMLDocument2 > spDoc =m_web.get_Document();        OnSetPass(spDoc);        ::CoUninitialize();}void CIEDoingDlg::OnSetPass(IHTMLDocument2 * pIHTMLDocument2){        IHTMLElementCollection* pElemColl = NULL;        HRESULT        hr1 = pIHTMLDocument2->get_all( &pElemColl );   //取得框架frame的集合        if( !pIHTMLDocument2 )        {                return;        }        HRESULT hr;        CComBSTR bstrTitle;        pIHTMLDocument2->get_title( &bstrTitle );        //取得文档标题        CComQIPtr< IHTMLElementCollection > spElementCollection;        hr = pIHTMLDocument2->get_forms( &spElementCollection );        //取得表单集合        CComQIPtr< IHTMLElement > pIHTMLEle;        hr =pIHTMLDocument2->get_body(&pIHTMLEle);        if ( FAILED( hr ) )         {                return;        }        long nFormCount=0;                                //取得表单数目        hr = spElementCollection->get_length( &nFormCount );        if ( FAILED( hr ) )        {                return;        }        for(long i=0; i<nFormCount; i++)        {                IDispatch *pDisp = NULL;        //取得第 i 项表单                hr = spElementCollection->item( CComVariant( i ), CComVariant(), &pDisp );                if ( FAILED( hr ) )         continue;                CComQIPtr< IHTMLFormElement > spFormElement = pDisp;                pDisp->Release();                long nElemCount=0;                        //取得表单中 域 的数目                hr = spFormElement->get_length( &nElemCount );                if ( FAILED( hr ) )                continue;                USES_CONVERSION;                for(long j=0; j<nElemCount; j++)                {                        CComDispatchDriver spInputElement;        //取得第 j 项表单域                        hr = spFormElement->item( CComVariant( j ), CComVariant(), &spInputElement );                        if ( FAILED( hr ) )        continue;                        CComVariant vID, vType;                        hr = spInputElement.GetPropertyByName( L"id", &vID );                        if( FAILED( hr ) )        continue;                        hr = spInputElement.GetPropertyByName( L"type", &vType );                        if( FAILED( hr ) )        continue;                        LPCTSTR lpVID  = vID.bstrVal ?                                OLE2CT( vID.bstrVal  ) : _T("NULL");                        LPCTSTR lpType = vType.bstrVal ?                                OLE2CT( vType.bstrVal ) : _T("NULL");                        CString strID(lpVID), strType(lpType);                        if (strID.CompareNoCase(_T("pp")) == 0 && strType.CompareNoCase(_T("password")) == 0){                                //是确认密码编辑框                                //GetUserNameFocus();                                CComVariant   vSetValue(_T("cctry123"));                                spInputElement.PutPropertyByName(L"value", &vSetValue );                        }                        OnClickRegBtn(pElemColl,_T("btlogin"));                }                 pDisp->Release();        }        //OnEnChangeEdit1();}// 点击按扭void CIEDoingDlg::OnClickRegBtn(IHTMLElementCollection * pElemColl, CString strElementId){         IDispatch *pDisp;                 HRESULT hr;         VARIANT index;         VARIANT varID;         V_VT(&index) = VT_I4;         V_I4(&index) = 0;         varID = StringToVariant(strElementId);         hr = pElemColl->item(varID, index, &pDisp);   // 获得按钮位置         if ( (hr == S_OK) && (pDisp != NULL) )          {                 IHTMLElement* pElem = NULL;               // 获得按钮元素接口                         hr = pDisp->QueryInterface(IID_IHTMLElement, (void**)&pElem);                 if (  (hr == S_OK) && (pElem != NULL) )                 {                         pElem->click();                       // 点击按钮                                 pElem->Release();                 }                 pDisp->Release();         }}// 类型转化VARIANT CIEDoingDlg::StringToVariant(CString str){         VARIANT variant;         VariantInit(&variant);         variant.vt = VT_BSTR;         variant.bstrVal = str.AllocSysString();         return variant;}// 认证码图片取得void CIEDoingDlg::OnGetCode(void){         CString path;         GetCurrentDirectory(MAX_PATH,path.GetBuffer(MAX_PATH));         path+=_T("\\Num.BMP");         URLDownloadToFile(NULL,_T("https://mail.qq.com/cgi-bin/getverifyimage?aid=23000101&f=html&ck=1&41202"),path ,0,NULL);         CString strPath =path;         CImage img;         HRESULT hr;         hr = img.Load(strPath);         if(!img.IsNull())         {                 HBITMAP hBitmap = img.Detach();                 CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC);                 if (pStatic != NULL)                 {                         pStatic->SetBitmap(hBitmap);                 }         }} 

读书人网 >VC/MFC

热点推荐