C/C++ 如何来自动优雅的涮别银家的贴子
被涮屏涮烦了,就分享一下如何用低调的c/c++来涮别人家的屏吧! 此处埋下三颗雷! 这不是啥新知识,也不是什么浅显的代码。下面,来淘淘这份经验,呼呼
我们要了解Web browser 这个控件,因为到目前为止,很少有浏览器能够被调用内核API,而Web browser 提供了IE的内核内容,就是我们可以用Ie提供的内核来自己设计一个简单的浏览器 当然,我们这儿并不是扯这个蛋。 但是为了后面说起来比较合理些 ,就只能翻山越岭的开始介绍了!
首先创建一个dlg,然后点击Acx control ,如果看见了mscro(简称) Web browser ,就双击两下,如果没看见,那就再去看看,很定是可以看得见的! 这些搞定之后,你就会看到下面这个黑乎乎的东西:
因为,前面说了这个界面不是分享到重点,所以就轻微的飘过。之后将这个dlg写成下面这般模样!!!
WebMFCDlg.h : 头文件
1 // WebMFCDlg.h : 头文件
2 //
3
4 #pragma once
5 #include "explorer1.h"
6
7
8 // CWebMFCDlg 对话框
9 class CWebMFCDlg : public CDialogEx
10 {
11 // 构造
12 DECLARE_DYNAMIC(CWebMFCDlg)
13 public:
14 CWebMFCDlg(CWnd* pParent = NULL); // 标准构造函数
15
16 // 对话框数据
17 enum { IDD = IDD_WEBMFC_DIALOG };
18
19 protected:
20 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
21
22
23 // 实现
24 protected:
25 HICON m_hIcon;
26
27 // 生成的消息映射函数
28 virtual BOOL OnInitDialog();
29 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
30 afx_msg void OnPaint();
31 afx_msg HCURSOR OnQueryDragIcon();
32 DECLARE_MESSAGE_MAP()
33 public:
34 CExplorer1 m_explo;
35 afx_msg void OnBnClickedOk();
36 DECLARE_EVENTSINK_MAP()
37 void OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl);
38
39 };
WebMFCDlg.cpp: 头文件
1 // WebMFCDlg.cpp : 实现文件
2 //
3
4 #include "stdafx.h"
5 #include "WebMFC.h"
6 #include "WebMFCDlg.h"
7 #include "afxdialogex.h"
8 #include <MsHTML.h>
9 #ifdef _DEBUG
10 #define new DEBUG_NEW
11 #endif
12
13
14 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
15
16
17 class CAboutDlg : public CDialogEx
18 {
19 public:
20 CAboutDlg();
21
22 // 对话框数据
23 enum { IDD = IDD_ABOUTBOX };
24
25 protected:
26 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
27
28 // 实现
29 protected:
30 DECLARE_MESSAGE_MAP()
31 };
32
33 CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
34 {
35 }
36
37 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
38 {
39 CDialogEx::DoDataExchange(pDX);
40 }
41
42 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
43 END_MESSAGE_MAP()
44
45
46 // CWebMFCDlg 对话框
47
48 IMPLEMENT_DYNAMIC(CWebMFCDlg, CDialogEx)
49
50 CWebMFCDlg::CWebMFCDlg(CWnd* pParent /*=NULL*/)
51 : CDialogEx(CWebMFCDlg::IDD, pParent)
52 {
53 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
54 }
55
56 void CWebMFCDlg::DoDataExchange(CDataExchange* pDX)
57 {
58 CDialogEx::DoDataExchange(pDX);
59 DDX_Control(pDX, IDC_EXPLORER1, m_explo);
60 }
61
62 BEGIN_MESSAGE_MAP(CWebMFCDlg, CDialogEx)
63 ON_WM_SYSCOMMAND()
64 ON_WM_PAINT()
65 ON_WM_QUERYDRAGICON()
66 ON_BN_CLICKED(IDOK, &CWebMFCDlg::OnBnClickedOk)
67 END_MESSAGE_MAP()
68
69
70 // CWebMFCDlg 消息处理程序
71
72 BOOL CWebMFCDlg::OnInitDialog()
73 {
74 CDialogEx::OnInitDialog();
75
76 // 将“关于...”菜单项添加到系统菜单中。
77
78 // IDM_ABOUTBOX 必须在系统命令范围内。
79 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
80 ASSERT(IDM_ABOUTBOX < 0xF000);
81
82 CMenu* pSysMenu = GetSystemMenu(FALSE);
83 if (pSysMenu != NULL)
84 {
85 BOOL bNameValid;
86 CString strAboutMenu;
87 bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
88 ASSERT(bNameValid);
89 if (!strAboutMenu.IsEmpty())
90 {
91 pSysMenu->AppendMenu(MF_SEPARATOR);
92 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
93 }
94 }
95
96 // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
97 // 执行此操作
98 SetIcon(m_hIcon, TRUE); // 设置大图标
99 SetIcon(m_hIcon, FALSE); // 设置小图标
100
101 // TODO: 在此添加额外的初始化代码
102 //com组件的变量
103
104 CComVariant vtUrl("http://hust.myubbs.com/forum.php?mod=forumdisplay&fid=11");
105 CComVariant vtEmpty; //NULL
106 m_explo.Navigate2(&vtUrl, &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);//打开指定的网页
107 m_explo.put_Silent(VARIANT_TRUE); //禁止脚本错误提示
108 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
109 }
110
111 void CWebMFCDlg::OnSysCommand(UINT nID, LPARAM lParam)
112 {
113 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
114 {
115 CAboutDlg dlgAbout;
116 dlgAbout.DoModal();
117 }
118 else
119 {
120 CDialogEx::OnSysCommand(nID, lParam);
121 }
122 }
123
124 // 如果向对话框添加最小化按钮,则需要下面的代码
125 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
126 // 这将由框架自动完成。
127
128 void CWebMFCDlg::OnPaint()
129 {
130 if (IsIconic())
131 {
132 CPaintDC dc(this); // 用于绘制的设备上下文
133
134 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
135
136 // 使图标在工作区矩形中居中
137 int cxIcon = GetSystemMetrics(SM_CXICON);
138 int cyIcon = GetSystemMetrics(SM_CYICON);
139 CRect rect;
140 GetClientRect(&rect);
141 int x = (rect.Width() - cxIcon + 1) / 2;
142 int y = (rect.Height() - cyIcon + 1) / 2;
143
144 // 绘制图标
145 dc.DrawIcon(x, y, m_hIcon);
146 }
147 else
148 {
149 CDialogEx::OnPaint();
150 }
151 }
152
153 //当用户拖动最小化窗口时系统调用此函数取得光标
154 //显示。
155 HCURSOR CWebMFCDlg::OnQueryDragIcon()
156 {
157 return static_cast<HCURSOR>(m_hIcon);
158 }
159
160 BEGIN_EVENTSINK_MAP(CWebMFCDlg, CDialogEx)
161 ON_EVENT(CWebMFCDlg, IDC_EXPLORER1, 273, CWebMFCDlg::OnNewwindow3Explorer1, VTS_PDISPATCH VTS_PBOOL VTS_UI4 VTS_BSTR VTS_BSTR)
162 END_EVENTSINK_MAP()
163
164 //放置调用IE
165 void CWebMFCDlg::OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl)
166 {
167 // TODO: Add your message handler code here
168 // TODO: 在此处添加消息处理程序代码
169
170 // 只在一个对话框中操作网页
171 *Cancel = TRUE;
172 CComVariant strUrl;
173 strUrl = bstrUrl;
174 CComVariant vInfo;
175 this->m_explo.Navigate2(&strUrl, &vInfo, &vInfo, &vInfo, &vInfo);
176 this->ShowWindow(SW_SHOW);
177 }
178 void CWebMFCDlg::OnBnClickedOk()
179 {
180 //开始不断的注入数据,哇哈哈哈,好开心!
181 while (1){
182
183 CComPtr < IDispatch > spDispDoc; //从com组件中分离
184 spDispDoc = m_explo.get_Document(); //得到文档
185 CComQIPtr< IHTMLDocument2 > spDocument2 = spDispDoc; //将其转化为document页面
186 CComQIPtr< IHTMLElementCollection > spElementCollection; //声明一个页面容器
187 if (SUCCEEDED(spDocument2->get_all(&spElementCollection))) //如果得到页面容器成功
188 {
189 CComPtr<IDispatch> spDisp1, spDisp2, spDisp; //com中封住的抽象的对象
190 HRESULT hr1, hr2,hr;
191 //取一个标题
192 hr1 = spElementCollection->item(CComVariant("subject"), CComVariant("0"), &spDisp1); //将热键获取赋予对象
193 //
194 hr2 = spElementCollection->item(CComVariant("message"), CComVariant("0"), &spDisp2);
195
196 hr = spElementCollection->item(CComVariant("topicsubmit"), CComVariant("0"), &spDisp);
197 if (SUCCEEDED(hr1) && SUCCEEDED(hr2)){
198 CComQIPtr<IHTMLInputElement> spElem1 = spDisp1; //装换为元素
199 CComQIPtr<IHTMLInputElement> spElem2 = spDisp2;
200 spElem1->put_value(CComBSTR("it's a test!")); //注入内容
201
202 spElem2->put_value(CComBSTR("这是一份来自电脑的重复输入,测试!it's a test !"));
203 if (SUCCEEDED(hr)){
204 CComQIPtr<IHTMLFormElement> spForm = spDisp;
205 spForm->submit();
206 }
207 }
208 }
209 m_explo.GoBack();
210 }
211 // TODO: 在此添加控件通知处理程序代码
212 //CDialogEx::OnOK();
213 }
下面说说如何去涮别人家的屏, 对于要刷别银家的屏,首先你得有个不错的浏览器。怎么才能说不错的浏览器呢? 第一滴: 你得始终不依靠别人家的浏览器。也就是说,无论点击啥网页,你都只能子在自己的浏览器里去跳转,A网站调到B页面,为啥? 因为我们不能让cookie莫名的中断了! 就如你登录再本地浏览器,出去跑了一圈回来,信息难免会损失。 第二点:不要出现脚本错误,你不能访问一个页面,然后就抬出N多这样的脚本错误!
一般的话都需要加上这句话在你的OnInitDialog()中;
1 m_explo.put_Silent(VARIANT_TRUE); //禁止脚本错误提示
然后要想一直留在自己的浏览器中: 首先得加上一个事件响应函数
在对话框.cpp中,需要实现
1 // CWebMFCDlg 对话框
2
3 IMPLEMENT_DYNAMIC(CWebMFCDlg, CDialogEx) //需要补充这句
4
5 CWebMFCDlg::CWebMFCDlg(CWnd* pParent /*=NULL*/)
6 : CDialogEx(CWebMFCDlg::IDD, pParent)
7 {
8 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
9 }
并且:
还需要不上这些
1 BEGIN_EVENTSINK_MAP(CWebMFCDlg, CDialogEx)
2 ON_EVENT(CWebMFCDlg, IDC_EXPLORER1, 273, CWebMFCDlg::OnNewwindow3Explorer1, VTS_PDISPATCH VTS_PBOOL VTS_UI4 VTS_BSTR VTS_BSTR)
3 END_EVENTSINK_MAP()
4
5 //放置调用IE
6 void CWebMFCDlg::OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl)
7 {
8 // TODO: Add your message handler code here
9 // TODO: 在此处添加消息处理程序代码
10
11 // 只在一个对话框中操作网页
12 *Cancel = TRUE;
13 CComVariant strUrl;
14 strUrl = bstrUrl;
15 CComVariant vInfo;
16 this->m_explo.Navigate2(&strUrl, &vInfo, &vInfo, &vInfo, &vInfo);
17 this->ShowWindow(SW_SHOW);
18 }
在对话框.h中:
1 // CWebMFCDlg 对话框
2 class CWebMFCDlg : public CDialogEx
3 {
4 // 构造
5 DECLARE_DYNAMIC(CWebMFCDlg) //需要添加上这句
6 public:
7 CWebMFCDlg(CWnd* pParent = NULL); // 标准构造函数
并且:
1 public:
2 CExplorer1 m_explo;
3 afx_msg void OnBnClickedOk();
4 DECLARE_EVENTSINK_MAP() //补充这句
5 void OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl); //和这句
实现了这些,然后只需要在对话框初始化函数中 添加如下:
1 CComVariant vtUrl("http://tieba.baidu.com/f?kw=%BA%FE%B1%B1%B9%A4%D2%B5%B4%F3%D1%A7&fr=ala0&tpl=5");
2 CComVariant vtEmpty; //NULL
3 m_explo.Navigate2(&vtUrl, &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);//打开指定的网页
然后运行就可以去看到这个了:
当然扯了这么多,并没什么鸟用。不过铺垫讲完了,到重点了? 如何才能将我们事先写好的数据,输入到html页面去呢? 而且还是用c++
恩! 这个问题,首先分析,用主流的五大浏览器,是很定搞不定的! 因为我们并不能去调用tm的API,所以我们只能想前面鲁的一大串一样! 去自己写一个浏览器
然后来实现这些调用IE公用的内核API!!!!
那么如何调用呢? 我们再来看看这图片:
这是浏览器原理里面的一部分内容! 偷偷的盗了一张好图,这里道声谢!
我们要将Ccomvarite 转化为document,然后在转化出HTMLHtmlElement元素即可!!!
首先我们需要引入: 头文件 #include<MsHTML.h>
1 CComPtr < IDispatch > sDDc; //从com组件中分离
2 sDDc = m_explo.get_Document(); //得到文档
3 CComQIPtr< IHTMLDocument2 > sDoc= sDDc; //将其转化为document页面
4 CComQIPtr< IHTMLElementCollection > spECn; //声明一个页面容器
5 if (SUCCEEDED(sDoc->get_all(&spECn))) //如果得到页面容器成功
6 {
7 CComPtr<IDispatch> spD1, spD2, spD; //com中封住的抽象的对象
8 HRESULT hr1, hr2,hr;
9 //取一个标题
10 hr1 = spECn->item(CComVariant("subject"), CComVariant("0"), &spD1); //将热键获取赋予对象
11 //
12 hr2 = spECn->item(CComVariant("message"), CComVariant("0"), &spD2);
13
14 hr = spECn->item(CComVariant("topicsubmit"), CComVariant("0"), &spD);
15 if (SUCCEEDED(hr1) && SUCCEEDED(hr2)){
16 CComQIPtr<IHTMLInputElement> spElem1 = spD1; //装换为元素
17 CComQIPtr<IHTMLInputElement> spElem2 = spD2;
18 spElem1->put_value(CComBSTR("it's a test!")); //注入内容
19
20 spElem2->put_value(CComBSTR("这是一份来自电脑的重复输入,测试!it's a test !"));
21 if (SUCCEEDED(hr)){
22 CComQIPtr<IHTMLFormElement> spForm = spD;
23 spForm->submit();
24 }
25 }
26 }
对于上面的这部分代码: 包含了数据的填写和提交,请结合上面的这张图,来理解!!!!
效果:
然后拉倒华科的考研论坛区测试了下:
第一个框中自动填充成功,但是第二,由于对方用js,写了预防注入的程序代码,就是必须输入前鼠标点击一下,不然输入不进去。所以这样单纯的填充,对于这种设置还是比较棘手!!! 当然如果c++,这边调用js来搞的话! 也许也未可知!
以后有时间再来做这方面的 探讨吧!! 希望这些分享,能带给大家一点点的帮助!!
---------------------------------------分割线-----------------------------
这篇文章过去太久了,久得连MFC已经没落的不成样子,隔了这么久,贴一下剩余的几个功能代码.
补充: 如何使用MFC调用JS来模拟鼠标点击网页
这里只是针对C++,ATL编写客户端时,调用微软API时常用的问题的解决方案:
1. 使用com组件调用js来模内点击网页按钮,避免使用复杂的dom树:
比如有这么一段html页面:
<input type="submit" id="su" value="百度一下" class="bg s_btn">
也就是百度首页:
首先在截图:
在console中输入:
document.getElementById("su").click()
会看到这:截图:
这说明这个js是生效的,然后我们再使用com组件调用这条js代码即可:
1 std::string strScript ="document.getElementById("su").click()";
2 // 获取 IHTMLDocument2 接口
3 IHTMLDocument2 *spDoc = NULL;
4 if (!webclient.get_Busy() && webclient.get_Document() != NULL)
5 webclient.get_Document()->QueryInterface(
6 ::IID_IHTMLDocument2, reinterpret_cast<void **>(&spDoc));
7 else
8 {
9 ::MessageBox(this->GetSafeHwnd(),L"IHTMLDocument2 接口获取失败",
10 L"Error", MB_OK | MB_ICONERROR);
11 return;
12 }
13
14 bool bSucceed(false);
15 if (spDoc)
16 {
17 // 获取 IHTMLWindow2 接口
18 IHTMLWindow2 *spWin;
19 VARIANT vRet;
20 HRESULT hr=spDoc->get_parentWindow(&spWin);
21 if (spWin)
22 {
23 CComBSTR bstrjs = (strScript.c_str());
24 CComBSTR bstrlan = SysAllocString(L"javascript");
25 long lRet = spWin->execScript(bstrjs, bstrlan, &vRet);
26 bSucceed = lRet == 0;
27 spWin->Release();
28 }
29 spDoc->Release();
30 }
第二个问题,那就是发帖子需要登陆,然后你还要获取到网站cookie才可以,所以下面我又补上获取cookie的代码.
2. 如何得到webbrower中的cookie值:
1 HRESULT hr;
2 IDispatch* lpDispatch;
3 lpDispatch = webclient.GetDocument();
4 IHTMLDocument2* lpDocument2;
5 hr = lpDispatch->QueryInterface(IID_IHTMLDocument2, (PVOID*)&lpDocument2);
6 if ( hr == S_OK )
7 {
8 BSTR bstrCookie;
9 hr = lpDocument2->get_cookie(&bstrCookie);
10 if ( hr == S_OK )
11 {
12 webCookie(bstrCookie);
13 }
14 lpDocument2->put_cookie(NULL);
15 pBody->Release();
16 lpDocument2->Release();
17 }
18 lpDispatch->Release();
至此,你就可以大胆的去制作刷广告机啦~~
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 用 Python 制作飞机大战小游戏
- SSM 单体框架 - 前端开发:视频讲解
- MyBatis 的 `<if test="">` 语句里面使用反单引号的问题
- 30 个Python代码实现的常用功能,精心整理版
- Java 后台开发面试题分享一
- IDEA 报错:no tests were found 和 UnsupportedOperationException
- Angular sandbox项目的tsconfig.json内容一览
- Java 后台开发面试题分享二
- axios 进行同步请求(async+await)
- Axios 各种请求方式传递参数格式
- axios POST提交数据的三种请求方式写法
- Json对象和Json字符串的区别
- 合并/拆分 Excel?Python、VBA轻松自动化
- (数据科学学习手札96)在geopandas中叠加在线地图
- 秋天的第一杯奶茶该买哪家?Python 爬取美团网红奶茶店告诉你