如何下载需要登录的网页?

baoyz 2009-12-03 04:55:46
使用
fileGet=(CHttpFile*)sess.OpenURL(LPCTSTR(Url));
fileGet->QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwBuffLen);
fileGet->QueryInfo(HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, &dwStatus, &dwBuffLen);
n = fileGet->Read(buf,sizeof(buf));
fileWrite.Write(buf,n);
fileWrite.Close();
可以下载不需要登录(或COOKIE)的网页。这部分已完成。

使用
AfxParseURL(LPCTSTR(Url), dwServiceType, strServer, strObject, nPort);
pHttpConn = session.GetHttpConnection(LPCTSTR(strServer), nPort);
fileGet = pHttpConn->OpenRequest(CHttpConnection::HTTP_VERB_GET, LPCTSTR(strObject));
fileGet->SendRequest();
bSuccess = fileGet->QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwBuffLen);
fileGet->QueryInfo(HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, &dwStatus, &dwBuffLen);
n = fileGet->Read(buf,sizeof(buf));
fileWrite.Write(buf,n);
fileWrite.Close();
也可以下载不需要登录(或COOKIE)的网页。这部分已完成。

但是有一些论坛,需要登录后才能浏览。
问:应该在哪里加入COOKIE信息,怎么加入?COOKIE信息是怎么获得的?
(用IE打开网站,得到的登录前后的2个COOKIE差别很大,也很乱。不知道哪条信息有用。)
COOKIE信息的获得和发送是怎么操作的?

=======================================================================================

还有用Navigate2(str, 0, NULL);可以打开需登录的网页。
1、如何让Navigate2(str, 0, NULL);只下载文本内容。即不下载图片,视频等?
2、如何在Navigate2(str, 0, NULL);下载后保存到指定位置?


请写代码或发个实例最好。
...全文
1146 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
baoyz 2009-12-09
  • 打赏
  • 举报
回复
100分不少了。怎么回复的人不多呀?

谁有可用的代码。我单独再给100分。
baoyz 2009-12-07
  • 打赏
  • 举报
回复
大家帮我看看。8楼的

m_pBrowser是怎么类型的?
cchLength是怎么得到的?
StringCchCopy((TCHAR*)hHTMLText, cchMax + 1, szHTMLText); 是什么函数?找不到呀。
baoyz 2009-12-07
  • 打赏
  • 举报
回复
TO:yschenwei
是呀,是一个技术论坛。可能网络不好速度……。只能抓下来离线看。可是所有的“抓站”软件都不行,抓下来的论坛帖页都是“请登录……”
alibabamt1 2009-12-05
  • 打赏
  • 举报
回复
make up!
Future_vc 2009-12-05
  • 打赏
  • 举报
回复
使用流加载和保存HTML内容
http://www.wangchao.net.cn/bbsdetail_28648.html

IPersist* 接口,以及它的附属方法,可以被用于Microsoft® Visual C++® 和 WebBrowser 控件使用流载入和保存HTML内容
  本文讨论载入HTML内容需要的步骤,分为以下几部分:
定位到 about:blank
DHTML 对象模型的有效性
使用 QueryInterface 获得IPersist*接口
使用IPersist*接口载入和保存HTML内容
载入和保存HTML元素数据
已知问题
参考
相关主题
  定位到 about:blank
  IWebBrowser2 接口的IWebBrowser2::Navigate2 方法 使得你可以让浏览器定位(Navigate)到一个URL。在下面的示例代码中, IWebBrowser2::Navigate2 方法 被用于定位到 about:blank 页面. 定位到这个空的页面确保了MSHTML 被加载,并且动态 HTML (DHTML) 对象模型中的 HTML 元素有效.
  本示例演示了如何让浏览器定位到一个空的页面。m_pBrowser 变量包含从WebBrowser 控件获得的 IWebBrowser2 接口指针。
  m_pBrowser->Navigate2( _T("about:blank"), NULL, NULL, NULL, NULL );
  DHTML 对象模型的有效性
  DHTML 对象模型 用于访问和操作HTML页面的内容,并且在页面装载之前不可用。你的应用程序通过处理WebBrowser 控件的DWebBrowserEvents2::DocumentComplete事件来判断一个页面是否被装载了。 这个事件可能被页面中的每个框架触发,并且在顶层文档载入完成时再触发一次。你可以通过比较事件传递的IDispatch 接口指针和WebBrowser 控件来判断DWebBrowserEvents2::DocumentComplete 事件是否是顶层框架的。
  这个WebBrowser DWebBrowserEvents2::DocumentComplete 事件的示例处理代码演示如何判断事件是否是顶层框架的, (如果是,)这指明HTML页面载入完成. 本示例也演示如何从一个内存块——在这个场合是一个包含需要显示的HTML内容的字符串——创建流。
  void myObject::DocumentComplete(LPDISPATCH pDisp, VARIANT* URL)
  {
   HRESULT hr;
   IUnknown* pUnkBrowser = NULL;
   IUnknown* pUnkDisp = NULL;
   IStream* pStream = NULL;
   HGLOBAL hHTMLText;
   static TCHAR szHTMLText[] = "<html><h1>流测试</h1><p>本HTML内容已经从流中加载。</html>";
   // 这个 DocumentComplete 事件是否是顶层框架窗口的?
   // 检查 COM 标识: 比较IUnknown 接口指针.
   hr = m_pBrowser->QueryInterface( IID_IUnknown, (void**)&pUnkBrowser );
   if ( SUCCEEDED(hr) )
   {
   hr = pDisp->QueryInterface( IID_IUnknown, (void**)&pUnkDisp );
   if ( SUCCEEDED(hr) )
   {
   if ( pUnkBrowser == pUnkDisp )
   { // 这是顶层框架窗口的DocumentComplete 事件 —— 页面 载入完成!
   // 建立一个包含HTML内容的流
   // 另外, 这个流可以是被传递过来的(而不是被创建的)
  
   size_t = cchLength;
   // TODO: 安全地判断 szHTMLText的长度,单位是TCHAR.
   hHTMLText = GlobalAlloc( GPTR, cchLength+1 );
  
   if ( hHTMLText )
   {
   size_t cchMax = 256;
   StringCchCopy((TCHAR*)hHTMLText, cchMax + 1, szHTMLText);
   // TODO: 在这里加入错误处理代码。
   hr = CreateStreamOnHGlobal( hHTMLText, TRUE, &pStream );
   if ( SUCCEEDED(hr) )
   {
   // 调用辅助函数让网络浏览器加载流。
   LoadWebBrowserFromStream( m_pBrowser, pStream );
   pStream->Release();
   }
   GlobalFree( hHTMLText );
   }
   }
   pUnkDisp->Release();
   }
   pUnkBrowser->Release();
   }
  }
  使用 QueryInterface 获得IPersis*等接口
  WebBrowser 控件的IWebBrowser2::get_Document 属性返回表示顶层框架的DHTML 对象模型的文档对象。MSHTML 通过文档对象和其他HTML元素对象,例如Frame, IFrame等等实现的IPersistStreamInit,IPersistFile等接口提供使用流载入和保存HTML的功能。对象的IDispatch 接口可用于通过使用QueryInterface和IID_IPersistStreamInit 等接口标识查询相应接口指针,如下列代码示例所述.
  HRESULT LoadWebBrowserFromStream(IWebBrowser2* pWebBrowser, IStream* pStream)
  {
  HRESULT hr;
  IDispatch* pHtmlDoc = NULL;
  IPersistStreamInit* pPersistStreamInit = NULL;
   // 返回文档对象.
   hr = pWebBrowser->get_Document( &pHtmlDoc );
   if ( SUCCEEDED(hr) )
   {
   // >查询 IPersistStreamInit接口
   hr = pHtmlDoc->QueryInterface( IID_IPersistStreamInit, (void**)&pPersistStreamInit );
   if ( SUCCEEDED(hr) )
   {
   // 初始化文档.
   hr = pPersistStreamInit->InitNew();
   if ( SUCCEEDED(hr) )
   {
   // 载入流内容
   hr = pPersistStreamInit->Load( pStream );
   }
   pPersistStreamInit->Release();
   }
   }
  }
  使用IPersist*接口载入和保存HTML内容
  IPersistStreamInit 接口具有用于从流初始化和载入HTML内容的InitNew 和Load 方法以及用于保存的Save方法。InitNew 方法初始化流到一个已知状态,Load 方法从流载入HTML内容,Save方法将HTML内容保存到流。
  IPersistFile 接口具有用于从磁盘文件载入和保存HTML内容的Load 和Save方法。
  在前面的示例代码中, HTML文档被初始化,并且HTML内容被从流中载入。
  注意 从Microsoft Internet Explorer 5开始,多于一次调用 IPersist* 接口的Load 方法 是可行的。在更早的版本中,每个MSHTML的实例只支持一次Load 调用。
  载入和保存HTML元素数据
  如果HTML元素支持使用IPersistStorage, IPersistStreamInit, 或者 IPersistMemory,那么也可以通过类似的代码载入和保存信息。
  对于网页中的ActiveX控件的信息的载入和保存,可以参考我的文章 如何: 通过HTML文档对象模型访问文档中的ActiveX控件的属性 (CSDN文档中心)来获得控件接口,然后查询ActiveX控件是否支持IPersist*接口。
yschenwei 2009-12-05
  • 打赏
  • 举报
回复
嘿嘿,貌似需要登录才能看的不多论坛啊,莫非楼主想抓取CSDN?
[Quote=引用楼主 baoyz 的回复:]
使用
fileGet=(CHttpFile*)sess.OpenURL(LPCTSTR(Url));
fileGet->QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwBuffLen);
fileGet->QueryInfo(HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, &dwStatus, &dwBuffLen);
n = fileGet->Read(buf,sizeof(buf));
fileWrite.Write(buf,n);
fileWrite.Close();
可以下载不需要登录(或COOKIE)的网页。这部分已完成。

使用
AfxParseURL(LPCTSTR(Url), dwServiceType, strServer, strObject, nPort);
pHttpConn = session.GetHttpConnection(LPCTSTR(strServer), nPort);
fileGet = pHttpConn->OpenRequest(CHttpConnection::HTTP_VERB_GET, LPCTSTR(strObject));
fileGet->SendRequest();
bSuccess = fileGet->QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwBuffLen);
fileGet->QueryInfo(HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, &dwStatus, &dwBuffLen);
n = fileGet->Read(buf,sizeof(buf));
fileWrite.Write(buf,n);
fileWrite.Close();
也可以下载不需要登录(或COOKIE)的网页。这部分已完成。

但是有一些论坛,需要登录后才能浏览。
问:应该在哪里加入COOKIE信息,怎么加入?COOKIE信息是怎么获得的?
(用IE打开网站,得到的登录前后的2个COOKIE差别很大,也很乱。不知道哪条信息有用。)
COOKIE信息的获得和发送是怎么操作的?

=======================================================================================

还有用Navigate2(str, 0, NULL);可以打开需登录的网页。
1、如何让Navigate2(str, 0, NULL);只下载文本内容。即不下载图片,视频等?
2、如何在Navigate2(str, 0, NULL);下载后保存到指定位置?


请写代码或发个实例最好。
[/Quote]
baoyz 2009-12-04
  • 打赏
  • 举报
回复
自己顶住等答案。
baoyz 2009-12-03
  • 打赏
  • 举报
回复
请教xsc2001:
我用

m_E1 = "http://www.126.com/";
m_E2 = "e:\\1.htm";
//////////////////////////////////////////////////////////////////////////
AfxParseURL(LPCTSTR(m_E1), dwServiceType, strServer, strObject, nPort);
try
{
if (pServer = session.GetHttpConnection(LPCTSTR(strServer), nPort))
{
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,strObject,NULL,1,NULL,NULL,INTERNET_FLAG_EXISTING_CONNECT);
}

if (pFile != NULL)
{
CString strRetHeader = "";
if(pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strRetHeader))
{
MessageBox(strRetHeader);
}
}
}

strRetHeader 为什么为空?
xsc2001 2009-12-03
  • 打赏
  • 举报
回复
首先需要登录网站,所以第一次用Post进行登录,而后解析得到cookie,然后每访问每一个页都要在header里添加cookie值。

CInternetSession sess;//Create session

CHttpFile* pFile;
//////////////////////////////////////////////
CHttpConnection *pServer = sess.GetHttpConnection(strServer, nPort);
if(pServer == NULL)
{
strDescript = "对不起,连接服务器失败!";
return false;
}
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,strObject,NULL,1,NULL,NULL,INTERNET_FLAG_EXISTING_CONNECT);
if(pFile == NULL)
{
strDescript = "找不到网络地址" + strUrl;
return false;
}

pFile -> AddRequestHeaders("Content-Type: application/x-www-form-urlencoded");
pFile -> AddRequestHeaders("Accept: */*");
pFile -> SendRequest(NULL,0,(LPTSTR)(LPCTSTR)strPara, strPara.GetLength()); //strPara是登录的参数,如username=abcdef&password=123456

CString strSentence;
DWORD dwStatus;
DWORD dwBuffLen = sizeof(dwStatus);
BOOL bSuccess = pFile->QueryInfo(
HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,
&dwStatus, &dwBuffLen);


通过pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strRetHeader);可到得到返回的信息头,从中就可以分析到cookie值

然后再提交请求时,在请求信息头中添加其cookie值,方法是:pFile -> AddRequestHeaders("Cookie: " + strCookie);
oyljerry 2009-12-03
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 baoyz 的回复:]
只是一个下载器,没有界面显示。

可以加两个CEDIT输入账号和密码。
应该怎么加入呢?head怎么加?
[/Quote]
看提交用户,密码的时候http包,然后自己构建对应的http请求
baoyz 2009-12-03
  • 打赏
  • 举报
回复
只是一个下载器,没有界面显示。

可以加两个CEDIT输入账号和密码。
应该怎么加入呢?head怎么加?
哈利路亚1874 2009-12-03
  • 打赏
  • 举报
回复
顶一下
ziplj 2009-12-03
  • 打赏
  • 举报
回复
CHttpFile可以自动管理cookie 不用自己管理
你只用提交账号 面目就可以了

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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