网页资源抓取

对于MSIE,可以使用微软提供的IHTMLDocument2的接口,获取源代码,解析源代码中的url地址,显示在列表中,根据用户的选择,将地址到导给flashget来下载

基本的步骤如下:

1。获得IE的窗口,我使用了类似spy++的抓窗口方法,即将鼠标定位在某个窗口中

2。获得网业的代码

3。解析url地址,并显示

4。将地址导给flashget

详细的实现如下:

1。获得IE的窗口

跟踪鼠标,获得鼠标释放时的位置,跟踪的代码很简单,如下

 case WM_LBUTTONDOWN:
  {
   SetCapture(hWnd);
   SetCursor(ghcrCapture);
   SendMessage(hWnd,STM_SETICON,(WPARAM)ghIconCaptured,0);
  }
  break;
 case WM_LBUTTONUP:
  {
   ReleaseCapture();
   SendMessage(hWnd,STM_SETICON,(WPARAM)ghIconCapture,0);
   HWND hDlg = GetParent(hWnd);
   SetCursor(LoadCursor(NULL,IDC_WAIT));
   DoCapture(hDlg);  //做2,3步骤的工作的函数
  }
  break;

获得窗口的句柄,并判断是否是webrowser

HWND GetWebBrowserWnd()
{
 POINT pt;
 GetCursorPos(&pt);

//获得窗口句柄
 HWND hwndWeb = WindowFromPoint(pt);
 if(!hwndWeb)
  return NULL;

//根据窗口类名判断是否是webbrowser窗口

 TCHAR szClassName[256];
 GetClassName(hwndWeb,szClassName,256);
 if(_tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0)
  return hwndWeb;

 return NULL;
}

2。获得源代码

(这部分是从msdn上演化的,为了大家方便,就帖出来吧)

首先获得IXMLDocument2的接口

BOOL GetIHtmlDocPtr(HWND hwndWeb,IHTMLDocument2**ppHtmlDoc)
{
 UINT nMsg = ::RegisterWindowMessage(_T("WM_HTML_GETOBJECT"));
 LRESULT lRes;
 ::SendMessageTimeout( hwndWeb, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
 HRESULT hr = ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *)ppHtmlDoc);
 return SUCCEEDED(hr);
}

其次,取得body对象,通过取得他的innerHtml来获得代码

 CComPtr<IHTMLElement> pElement;
 pIHtmlDoc->get_body(&pElement);
 CComBSTR strHtml;
 pElement->get_innerHTML(&strHtml)

3。分析源代码

可以使用正规则表达市来分析,不过我没有使用。我是自己一个字符一个字符的解析的。因此不过完善。代码比较长,而且难以理解。不能献丑了

4。把地址发送给flashget

flashget有com接口可以使用,是一个IDispatch接口,在没有头文件的情况下即可调用

可以通过字符“JetCar.Netscape”找到他的CLSID:

 CComPtr<IUnknown> pUnknown;
 CLSID clsid;
 if(FAILED(CLSIDFromProgID(L"JetCar.Netscape",&clsid)))
  return;
 if(FAILED(pUnknown.CoCreateInstance(clsid)))
  return;
 pUnknown->QueryInterface(IID_IDispatch,(void**)&m_pFlashGet);

m_pFlashGet是IDispatch*类型

这个对象编号为0x3的函数可以添加一个地址,调用如下

void CFlashGet::AddUrl(LPCTSTR lpszUrl,LPCTSTR lpszRef)
{
 _bstr_t  bstr;
 EXCEPINFO  excpInfo;
 UINT       argErr;
 DISPPARAMS dispParams;
 VARIANT    varRet;
 
 varRet.vt = VT_EMPTY;
 
 memset(&dispParams,0,sizeof(DISPPARAMS));
 dispParams.cArgs = 3;
 dispParams.rgvarg = new VARIANT[3];
 bstr = (lpszRef?lpszRef:lpszUrl);
 dispParams.rgvarg[0].vt = VT_BSTR;
 dispParams.rgvarg[0].bstrVal = SysAllocString(bstr);
 dispParams.rgvarg[1].vt = VT_BSTR;
 dispParams.rgvarg[1].bstrVal = SysAllocString(L"FlashGet 0.76");
 bstr = lpszUrl;
 dispParams.rgvarg[2].vt = VT_BSTR;
 dispParams.rgvarg[2].bstrVal = SysAllocString(bstr);
 m_pFlashGet->Invoke(0x3,IID_NULL,NULL,DISPATCH_METHOD,&dispParams,&varRet,&excpInfo,&argErr);
 SysFreeString(dispParams.rgvarg[0].bstrVal);
 SysFreeString(dispParams.rgvarg[1].bstrVal);
 SysFreeString(dispParams.rgvarg[2].bstrVal);
 delete []dispParams.rgvarg;
}

编号为0x4的函数可以添加一个地址列表,方法同上,就不罗嗦了

关于flashget 接口的详细用法,flashget官方网站的帮助中有代码,可以下载

需要注意的几个问题:

1。有很多网页,是有frame的,所以要遍历所有的frame,否则将得不到任何代码,这里有个例子,好象是从网上代码演化的,帖出来共享

void EnumFrame(IHTMLDocument2 * pIHTMLDocument2,HWND hMainDlg)
{
 if (!pIHTMLDocument2) return;
 
 HRESULT hr;
 
 CComPtr< IHTMLFramesCollection2 > spFramesCollection2;
 pIHTMLDocument2->get_frames( &spFramesCollection2 ); //取得框架frame的集合
 
 long nFrameCount=0;    //取得子框架个数
 hr = spFramesCollection2->get_length( &nFrameCount );
 if (FAILED (hr) || 0 == nFrameCount )
  return;
 
 for(long i=0; i<nFrameCount; i++)
 {
  CComVariant vDispWin2;  //取得子框架的自动化接口
  hr = spFramesCollection2->item(&CComVariant(i), &vDispWin2);
  if (FAILED (hr)) continue;
  
  CComQIPtr<IHTMLWindow2> spWin2 = vDispWin2.pdispVal;
  if(!spWin2) continue; //取得子框架的 IHTMLWindow2 接口
  
  CComPtr <IHTMLDocument2> spDoc2;
  spWin2->get_document(&spDoc2); //取得字框架的 IHTMLDocument2 接口
  
  GetFlashLink(spDoc2,hMainDlg);   //递归枚举当前子框架 IHTMLDocument2 上的表单form
 }
}

2。取得的代码都是unicode的,你可以直接对unicode处理,也可以转化后处理

3。地址的拼接。url有3种:1。绝对路径;2。相对与当前页的路径,3。相对于根的路径,表示方法是最前面是一个字符“/”表示根目录下的文件。

3。地址的过滤。我使用扩展名对地址过滤。不过,例如php,asp这些页面后有参数,需要把剔除参数后对扩展名比较。

还有就是隐藏在脚本里的地址了。这个我就不知道如何处理了。高手可以给点建议吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值