qq邮箱自动登录

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

一下子感觉无从下手,特别是怎么自动识别验证码,让人头大,求大神给个思路,最好能给出可用的代码,谢谢!
...全文
851 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
ppk_master 2012-03-21
  • 打赏
  • 举报
回复
感谢楼上的大大,太牛B了。
chyjp2008 2012-03-21
  • 打赏
  • 举报
回复



void CIEDoingDlg::OnEnChangeEdit1()
{
// TODO: 如果该控件是 RICHEDIT 控件,它将不
// 发送此通知,除非重写 CDialog::OnInitDialog()
// 函数并调用 CRichEditCtrl().SetEventMask(),
// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

UpdateData(TRUE);
GetDlgItem(IDC_EDIT1)->SetFocus();
CString s;
int is;
GetDlgItemText(IDC_EDIT1,s);
is=s.GetLength();
if (is==4)
{
OnCode();
SetDlgItemText(IDC_EDIT1,_T(""));
}
UpdateData(FALSE);

// TODO: 在此添加控件通知处理程序代码
}

// 调用验证码输入
void CIEDoingDlg::OnCode(void)
{
::CoInitialize(NULL); //初始化 COM 公寓
CComQIPtr < IHTMLDocument2 > spDoc =m_web.get_Document();
OnSetPassCode(spDoc);
::CoUninitialize();
}



// 传递验证码
void CIEDoingDlg::OnSetPassCode(IHTMLDocument2 * pIHTMLDocument2)
{
IHTMLElementCollection* pElemColl = NULL;
HRESULT hr1 = pIHTMLDocument2->get_all( &pElemColl );
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("vc")) == 0 && strType.CompareNoCase(_T("text")) == 0){
//是验证码编辑框
UpdateData(FALSE);
CComVariant vSetValue(m_code);
spInputElement.PutPropertyByName(L"value", &vSetValue );

}
OnClickRegBtn(pElemColl,_T("btlogin"));
//spFormElement->submit();
}
pDisp->Release();
}
}

void CIEDoingDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
m_web.Refresh();
}






chyjp2008 2012-03-21
  • 打赏
  • 举报
回复
汗,内容过长,接着发。



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);
}
}

}






chyjp2008 2012-03-21
  • 打赏
  • 举报
回复
先用图像算法对验证码进行去噪、分割、识别,获取验证码值,然后用webbrowser获取邮箱接口,提交账号、密码和验证码值即可。

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



// 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();
}
}

}

ppk_master 2012-03-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 z373375579 的回复:]
用SMTP吧
[/Quote]
我想做一个自动识别验证码的程序,不但是能登录邮箱,还能登录像csdn这样的论坛,因为每次输密码很麻烦。。
心死 2012-03-21
  • 打赏
  • 举报
回复
用SMTP吧

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧