C/C++ 如何来自动优雅的涮别银家的贴子
被涮屏涮烦了,就分享一下如何用低调的c/c++来涮别人家的屏吧! 此处埋下三颗雷! 这不是啥新知识,也不是什么浅显的代码。下面,来淘淘这份经验,呼呼
我们要了解Web browser 这个控件,因为到目前为止,很少有浏览器能够被调用内核API,而Web browser 提供了IE的内核内容,就是我们可以用Ie提供的内核来自己设计一个简单的浏览器 当然,我们这儿并不是扯这个蛋。 但是为了后面说起来比较合理些 ,就只能翻山越岭的开始介绍了!
首先创建一个dlg,然后点击Acx control ,如果看见了mscro(简称) Web browser ,就双击两下,如果没看见,那就再去看看,很定是可以看得见的! 这些搞定之后,你就会看到下面这个黑乎乎的东西:
因为,前面说了这个界面不是分享到重点,所以就轻微的飘过。之后将这个dlg写成下面这般模样!!!
WebMFCDlg.h : 头文件
// WebMFCDlg.h : 头文件
// #pragma once
#include "explorer1.h" // CWebMFCDlg 对话框
class CWebMFCDlg : public CDialogEx
{
// 构造
DECLARE_DYNAMIC(CWebMFCDlg)
public:
CWebMFCDlg(CWnd* pParent = NULL); // 标准构造函数 // 对话框数据
enum { IDD = IDD_WEBMFC_DIALOG }; protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现
protected:
HICON m_hIcon; // 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CExplorer1 m_explo;
afx_msg void OnBnClickedOk();
DECLARE_EVENTSINK_MAP()
void OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl); };
WebMFCDlg.cpp: 头文件
// WebMFCDlg.cpp : 实现文件
// #include "stdafx.h"
#include "WebMFC.h"
#include "WebMFCDlg.h"
#include "afxdialogex.h"
#include <MsHTML.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialogEx
{
public:
CAboutDlg(); // 对话框数据
enum { IDD = IDD_ABOUTBOX }; protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现
protected:
DECLARE_MESSAGE_MAP()
}; CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
} void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
} BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP() // CWebMFCDlg 对话框 IMPLEMENT_DYNAMIC(CWebMFCDlg, CDialogEx) CWebMFCDlg::CWebMFCDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CWebMFCDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
} void CWebMFCDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EXPLORER1, m_explo);
} BEGIN_MESSAGE_MAP(CWebMFCDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &CWebMFCDlg::OnBnClickedOk)
END_MESSAGE_MAP() // CWebMFCDlg 消息处理程序 BOOL CWebMFCDlg::OnInitDialog()
{
CDialogEx::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码
//com组件的变量 CComVariant vtUrl("http://hust.myubbs.com/forum.php?mod=forumdisplay&fid=11");
CComVariant vtEmpty; //NULL
m_explo.Navigate2(&vtUrl, &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);//打开指定的网页
m_explo.put_Silent(VARIANT_TRUE); //禁止脚本错误提示
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
} void CWebMFCDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
} // 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。 void CWebMFCDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), ); // 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + ) / ;
int y = (rect.Height() - cyIcon + ) / ; // 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
} //当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CWebMFCDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
} BEGIN_EVENTSINK_MAP(CWebMFCDlg, CDialogEx)
ON_EVENT(CWebMFCDlg, IDC_EXPLORER1, , CWebMFCDlg::OnNewwindow3Explorer1, VTS_PDISPATCH VTS_PBOOL VTS_UI4 VTS_BSTR VTS_BSTR)
END_EVENTSINK_MAP() //放置调用IE
void CWebMFCDlg::OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl)
{
// TODO: Add your message handler code here
// TODO: 在此处添加消息处理程序代码 // 只在一个对话框中操作网页
*Cancel = TRUE;
CComVariant strUrl;
strUrl = bstrUrl;
CComVariant vInfo;
this->m_explo.Navigate2(&strUrl, &vInfo, &vInfo, &vInfo, &vInfo);
this->ShowWindow(SW_SHOW);
}
void CWebMFCDlg::OnBnClickedOk()
{
//开始不断的注入数据,哇哈哈哈,好开心!
while (){ CComPtr < IDispatch > spDispDoc; //从com组件中分离
spDispDoc = m_explo.get_Document(); //得到文档
CComQIPtr< IHTMLDocument2 > spDocument2 = spDispDoc; //将其转化为document页面
CComQIPtr< IHTMLElementCollection > spElementCollection; //声明一个页面容器
if (SUCCEEDED(spDocument2->get_all(&spElementCollection))) //如果得到页面容器成功
{
CComPtr<IDispatch> spDisp1, spDisp2, spDisp; //com中封住的抽象的对象
HRESULT hr1, hr2,hr;
//取一个标题
hr1 = spElementCollection->item(CComVariant("subject"), CComVariant(""), &spDisp1); //将热键获取赋予对象
//
hr2 = spElementCollection->item(CComVariant("message"), CComVariant(""), &spDisp2); hr = spElementCollection->item(CComVariant("topicsubmit"), CComVariant(""), &spDisp);
if (SUCCEEDED(hr1) && SUCCEEDED(hr2)){
CComQIPtr<IHTMLInputElement> spElem1 = spDisp1; //装换为元素
CComQIPtr<IHTMLInputElement> spElem2 = spDisp2;
spElem1->put_value(CComBSTR("it's a test!")); //注入内容 spElem2->put_value(CComBSTR("这是一份来自电脑的重复输入,测试!it's a test !"));
if (SUCCEEDED(hr)){
CComQIPtr<IHTMLFormElement> spForm = spDisp;
spForm->submit();
}
}
}
m_explo.GoBack();
}
// TODO: 在此添加控件通知处理程序代码
//CDialogEx::OnOK();
}
下面说说如何去涮别人家的屏, 对于要刷别银家的屏,首先你得有个不错的浏览器。怎么才能说不错的浏览器呢? 第一滴: 你得始终不依靠别人家的浏览器。也就是说,无论点击啥网页,你都只能子在自己的浏览器里去跳转,A网站调到B页面,为啥? 因为我们不能让cookie莫名的中断了! 就如你登录再本地浏览器,出去跑了一圈回来,信息难免会损失。 第二点:不要出现脚本错误,你不能访问一个页面,然后就抬出N多这样的脚本错误!
一般的话都需要加上这句话在你的OnInitDialog()中;
m_explo.put_Silent(VARIANT_TRUE); //禁止脚本错误提示
然后要想一直留在自己的浏览器中: 首先得加上一个事件响应函数
在对话框.cpp中,需要实现
// CWebMFCDlg 对话框 IMPLEMENT_DYNAMIC(CWebMFCDlg, CDialogEx) //需要补充这句 CWebMFCDlg::CWebMFCDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CWebMFCDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
并且:
还需要不上这些
BEGIN_EVENTSINK_MAP(CWebMFCDlg, CDialogEx)
ON_EVENT(CWebMFCDlg, IDC_EXPLORER1, , CWebMFCDlg::OnNewwindow3Explorer1, VTS_PDISPATCH VTS_PBOOL VTS_UI4 VTS_BSTR VTS_BSTR)
END_EVENTSINK_MAP() //放置调用IE
void CWebMFCDlg::OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl)
{
// TODO: Add your message handler code here
// TODO: 在此处添加消息处理程序代码 // 只在一个对话框中操作网页
*Cancel = TRUE;
CComVariant strUrl;
strUrl = bstrUrl;
CComVariant vInfo;
this->m_explo.Navigate2(&strUrl, &vInfo, &vInfo, &vInfo, &vInfo);
this->ShowWindow(SW_SHOW);
}
在对话框.h中:
// CWebMFCDlg 对话框
class CWebMFCDlg : public CDialogEx
{
// 构造
DECLARE_DYNAMIC(CWebMFCDlg) //需要添加上这句
public:
CWebMFCDlg(CWnd* pParent = NULL); // 标准构造函数
并且:
public:
CExplorer1 m_explo;
afx_msg void OnBnClickedOk();
DECLARE_EVENTSINK_MAP() //补充这句
void OnNewwindow3Explorer1(LPDISPATCH* ppDisp, BOOL* Cancel, unsigned long dwFlags, LPCTSTR bstrUrlContext, LPCTSTR bstrUrl); //和这句
实现了这些,然后只需要在对话框初始化函数中 添加如下:
CComVariant vtUrl("http://tieba.baidu.com/f?kw=%BA%FE%B1%B1%B9%A4%D2%B5%B4%F3%D1%A7&fr=ala0&tpl=5");
CComVariant vtEmpty; //NULL
m_explo.Navigate2(&vtUrl, &vtEmpty, &vtEmpty, &vtEmpty, &vtEmpty);//打开指定的网页
然后运行就可以去看到这个了:
当然扯了这么多,并没什么鸟用。不过铺垫讲完了,到重点了? 如何才能将我们事先写好的数据,输入到html页面去呢? 而且还是用c++
恩! 这个问题,首先分析,用主流的五大浏览器,是很定搞不定的! 因为我们并不能去调用tm的API,所以我们只能想前面鲁的一大串一样! 去自己写一个浏览器
然后来实现这些调用IE公用的内核API!!!!
那么如何调用呢? 我们再来看看这图片:
这是浏览器原理里面的一部分内容! 偷偷的盗了一张好图,这里道声谢!
我们要将Ccomvarite 转化为document,然后在转化出HTMLHtmlElement元素即可!!!
首先我们需要引入: 头文件 #include<MsHTML.h>
CComPtr < IDispatch > sDDc; //从com组件中分离
sDDc = m_explo.get_Document(); //得到文档
CComQIPtr< IHTMLDocument2 > sDoc= sDDc; //将其转化为document页面
CComQIPtr< IHTMLElementCollection > spECn; //声明一个页面容器
if (SUCCEEDED(sDoc->get_all(&spECn))) //如果得到页面容器成功
{
CComPtr<IDispatch> spD1, spD2, spD; //com中封住的抽象的对象
HRESULT hr1, hr2,hr;
//取一个标题
hr1 = spECn->item(CComVariant("subject"), CComVariant(""), &spD1); //将热键获取赋予对象
//
hr2 = spECn->item(CComVariant("message"), CComVariant(""), &spD2); hr = spECn->item(CComVariant("topicsubmit"), CComVariant(""), &spD);
if (SUCCEEDED(hr1) && SUCCEEDED(hr2)){
CComQIPtr<IHTMLInputElement> spElem1 = spD1; //装换为元素
CComQIPtr<IHTMLInputElement> spElem2 = spD2;
spElem1->put_value(CComBSTR("it's a test!")); //注入内容 spElem2->put_value(CComBSTR("这是一份来自电脑的重复输入,测试!it's a test !"));
if (SUCCEEDED(hr)){
CComQIPtr<IHTMLFormElement> spForm = spD;
spForm->submit();
}
}
}
对于上面的这部分代码: 包含了数据的填写和提交,请结合上面的这张图,来理解!!!!
效果:
然后拉倒华科的考研论坛区测试了下:第一个框中自动填充成功,但是第二,由于对方用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();
至此,你就可以大胆的去制作刷广告机啦~~
C/C++ 如何来自动优雅的涮别银家的贴子的更多相关文章
- (八)solr7实现搜索框的自动提示并统计词频
solr7实现搜索框的自动提示并统计词频 1:用solr 的suggest组件,统计词频相对麻烦. 2:用TermsComponent,自带词频统计功能. Terms组件提供访问索引项的字段和每个词 ...
- Linux基本操作命令总结
1.命令基本格式 root用户:[root@localhost ~] # 或者普通用户:[hadoop@localhost ~] $ 用户@主机名 目录 [#|$]管理员类型 ...
- CSS遮罩——如何在CSS中使用遮罩
Css遮罩是2008年4月由苹果公司添加到webkit引擎中的.遮罩提供一种基于像素级别的,可以控制元素透明度的能力,类似于png24位或png32位中的alpha透明通道的效果. 图像是由rgb三个 ...
- web前端面试试题总结---css篇
CSS 介绍一下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的? (1)有两种, IE 盒子模型.W3C 盒子模型: (2)盒模型: 内容(content).填充(padding).边界(m ...
- 从 0 到 1,Java Web 网站架构搭建的技术演进
初始搭建 最开始,就是各种框架一搭,然后扔到 Tomcat 容器中跑,这时候我们的文件.数据库.应用都在一个服务器上. 服务分离 随着系统的上线,用户量也会逐步上升,很快一台服务器已经满足不了系统的负 ...
- 前端开发面试题-CSS(转载)
本文由 本文的原作者markyun 收集总结. 介绍一下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的? (1)有两种, IE 盒子模型.W3C 盒子模型: (2)盒模型: 内容(conte ...
- <转>大型分布式网站术语浅析
夜半睡起看书,看到一篇关于分布式网站性能优化术语的文章,个人觉得不错,分享出来... 原文地址:大型分布式网站术语分析 一.I/O优化 1.增加缓存,减少磁盘的访问次数. 2.优化磁盘的管理系统,设计 ...
- cobbler部署centos6与centos7系列
cobbler部署centos6与centos7系列 转载自:http://www.jianshu.com/p/a4bed77bf40d 版权声明:完全抄自 http://www.jianshu.co ...
- 从0到1,Java Web网站架构搭建的技术演进
俗话说得好,冰冻三尺非一日之寒,滴水穿石非一日之功,罗马也不是一天就建成的,对于开发人员来说,一个好的架构并不是一蹴而就的. 初始搭建 最开始,就是各种框架一搭,然后扔到 Tomcat 容器中跑,这时 ...
随机推荐
- 大商创开通用户和店铺 sql追踪
添加用户(账号:wmy123 ,密码:wzd222,id:69)INSERT INTO `dsc1`.`dsc_users` (user_name,mobile_phone,email,passwor ...
- tween.js是一款可生成平滑动画效果的js动画库。tween.js允许你以平滑的方式修改元素的属性值。它可以通过设置生成各种类似CSS3的动画效果。
简要教程 tween.js是一款可生成平滑动画效果的js动画库.相关的动画库插件还有:snabbt.js 强大的jQuery动画库插件和Tweene-超级强大的jQuery动画代理插件. tween. ...
- LUA OOP编程实现方法
lua原生不支持OOP特性 确实如此, 同时可以采用其它lua代码的方式实现OOP的特性. OOP四大特性 抽象 封装 继承 多态 http://www.cnblogs.com/xiaosongluf ...
- jsp:中文乱码解决
说明:request乱码指的是:浏览器向服务器发送的请求参数中包含中文字符,服务器获取到的请求参数的值是乱码: response乱码指的是:服务器向浏览器发送的数据包含中文字符,浏览器中显示的是乱码: ...
- 使用plsql执行计划进行sql调优(转载)
一段SQL代码写好以后,可以通过查看SQL的执行计划,初步预测该SQL在运行时的性能好坏,尤其是在发现某个SQL语句的效率较差时,我们可以通过查看执行计划,分析出该SQL代码的问题所在. 那么,作为开 ...
- 【001:ubuntu下搭建ESP8266开发环境--编辑 编译 下载】
系统环境:ubuntu 16.04 TLS 64BIT 编辑器: Eclipse CDT 版本 编译器:xtensa-lx106-elf 交叉编译工具链 下载工具:esptool.py pyseria ...
- jQuery 选择器 (基础恶补之二)
返回 CSS 属性 如需返回指定的 CSS 属性的值,请使用如下语法: css("propertyname"); 下面的例子将返回首个匹配元素的 background-color ...
- CentOS7安装Apache2.4+PHP5.6
linux系统CentOS7 先下载Apache需要依赖的软件 1.APR 下载地址http://apr.apache.org/download.cgi wget下载路径http://mirror.b ...
- 第三章 对象(JavaScript:语言精粹)
对象是属性的容器,其中每个属性都有名字和值. 3.0. 概览:对象字面量 | 检索 | 更新 | 引用 | 原型 | 反射 | 枚举 | 删除 | 减少全局变量污染 3.1. 对象字面量 ...
- shell & dialog
最近使用dialog写图形自动化shell脚本, 功能很强大,功能不是非常多但是足够用.想写一篇linux下dialog的使用方法,虽然命令不多,但是写起来也需要下很大功夫,而且不一定写得更好,在网 ...