超越自我, 挑站高手! UP无分!

zswzwy 2004-04-18 10:35:39
本人最近想学习网络编程,有几个问题想请教高手!

1、如何在程序中控制一个网页的行为?例如,我要在一个搜索引擎里搜索一个关键字, 在不打开网页的同时如何操作?

2、如何获取一个网页上指定的代码部分?例如,我要取得一段新闻和一个图片,其它内容不要.

3、如可自动生成一个网页?

谢谢各位,分可以再加!
...全文
72 48 打赏 收藏 转发到动态 举报
写回复
用AI写文章
48 条回复
切换为时间正序
请发表友善的回复…
发表回复
bbol 2004-04-27
  • 打赏
  • 举报
回复
不用置顶吧,这问题!
canjian 2004-04-25
  • 打赏
  • 举报
回复
学习
Chice_wxg 2004-04-25
  • 打赏
  • 举报
回复

i am very surprised to see that this topic is top-locked ....

how difficulty is it?

easy .................. hard
|
Here


1、向服务器80 port 发送请求。 HTTP协议说的很明白。

2、需要做HTML Parser。其实很好分析,HTML的tag非常明显。
如果嫌麻烦,可以后台初始化一个IE实例,用它来处理,前台读结果

3、IE的documnt支持write方式把 HTML代码写到一个页面中并显示出来。
如果要生成本地文件,只要看看HTML的代码就明白了。
蒋晟 2004-04-25
  • 打赏
  • 举报
回复
关于网页的分析部分,可以参见
https://www.microsoft.com/china/msdn/catalog/web/
蒋晟 2004-04-25
  • 打赏
  • 举报
回复
我记得很久之前就写过这么一篇文章的把
http://www.csdn.net/Develop/read_article.asp?id=21702
文章的示例代码有一个已知BUG,如果启用自动化浏览器脚本,而且在脚本中使用布尔型变量,退出的时候会有问题。修复的方法参见微软知识库文章Q199315 FIX: Method with BOOL* Parameter Type Overwriting Memory in Visual Basic


蒋晟 2004-04-25
  • 打赏
  • 举报
回复
我记得很久之前就写过这么一篇文章的把
http://www.csdn.net/Develop/read_article.asp?id=21702
文章的示例代码有一个已知BUG,如果启用自动化浏览器脚本,而且在脚本中使用退出的时候会有问题。
nanfeng231 2004-04-25
  • 打赏
  • 举报
回复
study!
关注
_xiao 2004-04-23
  • 打赏
  • 举报
回复
我觉得楼上的方法虽然行得通,但都太复杂,要做太多底层的解析工作,其实既然微软已在IE里完美地做完html的解析了,我们何不顺手拿过来用呢?

在对话框上使用微软的WebBrowse控件,如果不想让用户看见工作过程可以将它设为隐藏,然后就可以通过COM接口与WebBrowse打交道了(其实IE就是一个单文档框架加一个WebBrowse控件构成的),通过COM接口可以控制WebBrowse浏览任何IE可以浏览的网页,当然也包括向搜索引擎发送请求和获得搜索结果了,也可随意操作网页上的任何一个元素,动态获得和改变其内容,有时使用C语言操作并不一定方便,这时甚至可以让WebBrowse实时运行一段"JavaScript"或"VBScript"脚本来得到你想要的效果,非常之方便

至于COM接口的知识帖主就是轻车熟路的了,IWebBrowse等接口的用法在msdn上一应俱全
red-fly 2004-04-23
  • 打赏
  • 举报
回复
这得学习学习

今天得搬个凳子学习,站着受不了
边城无名 2004-04-23
  • 打赏
  • 举报
回复
好好学习,天天向上!
fanfyj 2004-04-21
  • 打赏
  • 举报
回复
收藏
caire1983 2004-04-21
  • 打赏
  • 举报
回复
我帮你解决这三个问题,你给我一个星怎么样?
Ailong 2004-04-21
  • 打赏
  • 举报
回复
Windows网络编程
TCP/IP的三卷本(对你目前应用来说初略了解网络的各个术语即可,不用看完)
然后看本介绍HTML的书籍,再看看相关的rfc就可以了。
去网页开发论坛看看别人的讨论,可以熟悉对网页的感觉。
辞多一撇 2004-04-21
  • 打赏
  • 举报
回复
1、俺想这里不应该用控制吧,我想不就是自己根据HTTP直接取网页,或按搜索引擎的要求送请求吧,再取回结果!

2、俺的是个笨办法,取下网页后,自己分析,截取需要的地方。但我想最终的实现会头痛死人吧!

3、这个简单,看看HTML吧!哈哈
top_hipster 2004-04-21
  • 打赏
  • 举报
回复
没什么难度和创意,不应该置顶吧?
FireEmissary 2004-04-21
  • 打赏
  • 举报
回复
还是要up
byf2002 2004-04-20
  • 打赏
  • 举报
回复
第三个问题

自己按HTML格式写文件就可以了
byf2002 2004-04-20
  • 打赏
  • 举报
回复
在取得选取网页内容之后,需要对HTML内容进行重新编辑以获得正确的显示,CheckData函数便是做这个工作的这个函数对HTML内容中图像信息的地址进行编辑,如果图像保存在本地则使用本地图像,如果图像没有下载保持原样。
BOOL CheckData(const LPCTSTR data,
const LPCTSTR host,
const LPCTSTR path,
DWORD Number,
std::string &outstring)
{
char chImgPath[1024];//图像路径 !:由于有些图像路径可能会很长所以申请内存多一点
char chImgSrc[MAX_PATH];//图像地址
char chDownLoadPath[MAX_PATH];//下载图像文件路径
char chWriteImgSrc[MAX_PATH];//图像文件路径

memset(chImgPath,0,1024);
memset(chImgSrc,0,MAX_PATH);
memset(chDownLoadPath,0,MAX_PATH);
memset(chWriteImgSrc,0,MAX_PATH);

char dirname[20];//根目录名
ltoa(Number,dirname,10);

try{
//查找是否有<img标记
const char *p1 = FindString(data,"<img");
const char *p2 = FindString(p1,"src=\"");
const char *p3 = FindString(p2+5,"\"");
const char *p4 = FindString(p1,">");
if(p1 == NULL||p2 == NULL||p3 == NULL||p4 == NULL)
return FALSE;

//找到一个图像文件标记

//拷贝图像链接之前的文字
int n = p4-p1+1;

strncpy(chImgPath,p1,n);
outstring.append(data,p2-data+5);

//提取图像链接

n = p3-p2-5;
strncpy(chImgSrc,p2+5,n);
if(FindString(chImgSrc,"http://") == NULL){
if(FindString(chImgSrc,".."))
strcpy(chImgSrc,&chImgSrc[2]);
sprintf(chDownLoadPath,"%s%s",host,chImgSrc);
sprintf(chWriteImgSrc,"%s//%s%s",path,dirname,chImgSrc);
}else{
strcpy(chDownLoadPath,chImgSrc);
const char *p5 = FindString(chImgSrc+7,"/");
sprintf(chWriteImgSrc,"%s\\%s%s",path,dirname,&chImgSrc[p5-chImgSrc]);
}
char Output[MAX_PATH];
sprintf(Output,"图像地址:%s\r\n存盘地址:%s\r\n主机地址:%s\r\n",chImgSrc,chWriteImgSrc,host);
SaveCharToFile(Output,debugpath);
n = strlen(chWriteImgSrc);
for(int i=0;i<n;i++){
if(chWriteImgSrc[i] == ''''/'''')
chWriteImgSrc[i] = ''''\\'''';
}

//在下载之前先建立保存图像文件的路径
CreateAllDirectory(chWriteImgSrc);

//下载图像文件
HRESULT hr = URLDownloadToFile( NULL, chDownLoadPath, chWriteImgSrc, 0, NULL);
if( SUCCEEDED(hr))//
{
const char *p6 = FindString(chDownLoadPath+7,"/");
sprintf(chWriteImgSrc,"%s%s",dirname,&chDownLoadPath[p6-chDownLoadPath]);
//将存盘的路径保存进字符串
}else{
strcpy(chWriteImgSrc,chDownLoadPath);
//没有下载成功将原始路径保存进
}
outstring.append(chWriteImgSrc);
outstring.append(p3,p4-p3+1);
BOOL ret = CheckData(p4+1,host,path,Number,outstring);
if(!ret){
outstring.append(p4+1);
}
}catch(...){
return FALSE;
}
return TRUE;
}

其他几个辅助函数这里简单介绍,详细内容请参看源代码

函数:void SaveCharToFile
功能:将字符串保存为给定文件名
const LPCTSTR data,//[IN] 给定待保存的数据
const LPCTSTR saveFileName,//[IN]给定文件名
BOOL flag = FALSE//[IN]追加写入还是覆盖标志

函数:const char *FindString
功能:在给定字符串中查找给定字符串
const LPCTSTR source,//[IN] 给定源字符串的数据
const LPCTSTR key)//[IN]待查字符串

函数:void CreateAllDirectory
功能:创建给定路径的所有未建目录
const char* AllPath)//[IN] 需要创建的详细目录
例如 输入为:"d:\a\b\c\d"则在D盘下创建相应a,b,c,d相应目录
  好了,到此为止,我们已经做成一个取得网页选取内容的并保存在本地的程序,你可以举一反三,将它应用到更有趣更有用的领域。
这个程序是我研究了一周才写完的,其中取得domument的方法我觉得很笨,可我现在没有找到好办法,希望能够抛砖引玉,有更好的方法别忘了告诉我,我的Email:lgtest@sina.com欢迎来信讨论。




byf2002 2004-04-20
  • 打赏
  • 举报
回复
第二个问题

http://www.vckbase.com/document/viewdoc/?id=1093


采集网页选定部分全攻略


作者:龙仪

下载源代码

  在 VCKBASE 混了这么久竟然没有写出一篇文章,想想很是惭愧,每当在这里看到一篇好文,这种感觉尤甚,总结我在程序员加油站中的一些技术点写了这个文章(虽然程序员加油站还要继续开发,但是由于时间关系不知道什么时候能完成),如果有时间我还会写一些文章的,我的写作水平可能很差,希望读者能够包涵。

程序原理:

一、在IE菜单中加入菜单项

  在注册表HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt项下建立一个新项,项的名称即为出现在菜单中的标题
将新建项的默认值设定为一个URL地址,当用户点击菜单项后,IE就会调用URL指向的页面中的脚本。

二、如何控制菜单项在合适的时候显示

  下面再介绍一下上面注册项中Contexts项的作用,通过该项可以制定菜单项在右键点击IE中的什么对象时出现,它可以为以下值的“或”组合
 对象 值
缺省 0x1
图片 0x2
控件 0x4
表单域 0x8
选择文本 0x10
锚点 0x20
超链接 0x22


例如上面我们希望菜单项在用户点击图片或者超链接时出现,那么我们就将值设置为

dword:00000022
既在点击图片 或者 锚点时出现菜单。一个锚点是页面中描述一个超链接的对象。如果不设置Contexts 项,则菜单项会在点击任何对象时出现在右键菜单中。

注:
  一二部分我引用了《如何在IE右键菜单中添加菜单项以及如何添加IE任务栏按钮》这篇文章的部分内容,详细内容请看:

http://www.csdn.net/develop/read_article.asp?id=3621
三、编辑点击菜单项执行的script脚本

  这个脚本的文件名和1中的链接文件一致这个是我用的脚本:

<script language="VBScript">

Sub OnContextMenu()
set nc=CreateObject("Test2.testa.1")
nc.GetHtmlText()
end sub

Call OnContextMenu()
</script>
//看到网海拾贝中这样用
<script language="VBScript">

Sub OnContextMenu()
NCWEBPAGE=1
NCSELWEBPAGE=2
NCSELTEXT=3
NCALLTEXT=4
NCIMAGE=5
NCALLIMAGE=6
NCALLLINK=7
NCALLLINKTITLE=8
NCSELSOURCECODE=9
NCSOURCECODE=10

On Error Resume Next
set nc=CreateObject("NcActive.NcCollect")
if err<>0 then
MsgBox("网海拾贝没有正确安装")
else
//但是这个参数至今不知道如何在控件中得到
call Nc.Gethtmldoc(NcSelText,external.menuArguments.document)
end if
end sub

Call OnContextMenu()
</script>

四、在注册表中加入

HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall
\\程序员加油站加入ArticlePath - 文档存盘路径(string),ArticleNumber -文档序号(dword)。

五、写一个ATL的DLL,就是上面脚本中调用的那个对象,提供一个接口GetHtmlText(),看到有些其他程序使用external.menuArguments.document做为参数,可是我没试验成功,无法直接获得其中的document所以只能用笨方法了,取得当前窗口,然后取得IE子窗口的句柄,然后取得document指针,取得选取的内容,然后保存网页,并下载图片。
  下面就介绍一下ATL组件的制作,主要技术包括ATL编程,IE编程,注册表操作。
1,用ATL COM模板创建一个工程
2,加入一个接口testa
3,加入Urlmon.Lib 和 #include <urlmon.h>
4,加入接口函数GetHtmlText()
实现如下:

STDMETHODIMP Ctesta::GetHtmlText()
{
//保存网页内容的目录
char chFilePath[MAX_PATH];
DWORD Number = 0;

CRegistry reg;
reg.Open(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\程序员加油站\\");
BOOL ret = reg.ReadDWORD("ArticleNumber",&Number);
if(!ret)
return S_FALSE;

//读取保存网页文件的目录
ret = reg.ReadString("ArticlePath",chFilePath);
if(!ret)
return S_FALSE;

//取得当前活动窗口的窗口句柄
HWND hWnd = GetActiveWindow();


CoInitialize( NULL );

//显式装载 MSAA 判断是否被安装
HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
if ( hInst != NULL )
{
if ( hWnd != NULL )
{
HWND hWndChild=NULL;
// 取得当前窗口的IE子窗口指针
::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
if ( hWndChild )
{
//定义IE文档
CComPtr pHTMLDoc;
LRESULT lRes;

//由于WM_HTML_GETOBJECT非Windows标准消息,所以需要RegisterWindowMessage
UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes );

LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, _T("ObjectFromLresult") );
if ( pfObjectFromLresult != NULL )
{
HRESULT hr;
//获取网页的IHTMLDocument2接口
hr = (*pfObjectFromLresult)( lRes, IID_IHTMLDocument, 0, (void**)&pHTMLDoc );
if ( SUCCEEDED(hr) )
{
CComPtr pSelObj;
CComPtr pTxtRange;

//根据IHTMLDocument2指针取得IHTMLSelectionObject接口指针
pHTMLDoc->get_selection(&pSelObj);
//再获得IHTMLTxtRange指针
hr = pSelObj->createRange((IDispatch**)&pTxtRange);
if(!CheckResult(hr,"pTxtRange"))
return hr;
//选择所有被选择的内容
pTxtRange->select();

BSTR bstrTxt,bstrTxt1;
char strPath[MAX_PATH];
char *strTxt = NULL;
char*strTxt1 = NULL;

//取得主站域名
CComPtr pLocation;
pHTMLDoc->get_location(&pLocation);
pLocation->get_hostname(&bstrTxt1);
strTxt1 = _com_util::ConvertBSTRToString(bstrTxt1);

sprintf(strPath,"http://%s",strTxt1);
SaveCharToFile(strTxt1,debugpath);

//取得选中的内容
pTxtRange->get_htmlText(&bstrTxt);
strTxt = _com_util::ConvertBSTRToString(bstrTxt);

//下载内容中的图片资源,并修改相应链接
std::string webpage;
char chSavePath[MAX_PATH];
sprintf(chSavePath,"%s\\T%ld.htm",chFilePath,Number);
CreateAllDirectory(chSavePath);

//取得所有图片资源并保存网页
if(CheckData(strTxt,strPath,chFilePath,Number,webpage) == FALSE)
SaveCharToFile(strTxt,chSavePath,TRUE);
else
SaveCharToFile(webpage.c_str(),chSavePath,TRUE);
BOOL ret = reg.WriteDWORD("ArticleNumber",++Number);
//释放内存
if(strTxt1)
delete[] strTxt1;
if(strTxt)
delete[] strTxt;
SysFreeString(bstrTxt1); // 用完释放
SysFreeString(bstrTxt); // 用完释放
}
}
}
} // else Internet Explorer is not running
::FreeLibrary( hInst );
} // else Active Accessibility is not installed
CoUninitialize();

return S_OK;
}


自由的风 2004-04-20
  • 打赏
  • 举报
回复
好文,值得学习,收藏
加载更多回复(28)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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