C++抓取网页源代码

#include "stdafx.h"
#include <winsock.h>             //相关的头文件
#include <iostream>

#pragma comment(lib,"ws2_32.lib")//VS下winsock编程一定要加这句话 不然会出错


using namespace std;

int UrlSnap(char* URL,char* &pageBuf)//自定义的抓取网页的函数,这里第二个参数使用了&引用类型,类似于delphi中的var 修饰
{
	WSADATA  wsa;
	if(WSAStartup(0x101,&wsa)!=0)
	{MessageBox(0,TEXT("Load winsock Failed"),TEXT("Erro"),MB_OK);}
//在vs编译器中对需要使用unicode宽字符的地方都要用TEXT宏,如果要输  出显示宽字符,可以使用wcout<<来输出,或者使用printf("%ws",string),用%ws进行输出格式控制
	char  request[512]="GET / HTTP/1.0\r\nHost: ";
	strcat_s(request,URL);
	strcat_s(request,"\r\nConnection: Close\r\n\r\n");
// 字符串操作的一系列函数:strcmp,strcat,strlen因为不够安全都已经停止使用,而改用其安全类型的strcat_s,strcmp_s,strlen_s等,对于宽字符则使用lstrcat,lstrcmp,lstrlen等

	struct hostent* ph=gethostbyname(URL);
	if(ph==NULL)
	{MessageBox(0,TEXT(" Failed in gethostbyname"),TEXT("Erro"),MB_OK);}
	struct in_addr  inAddr;
	LPSTR  lpaddr=ph->h_addr;//获取的地址是网络字节顺序
	memmove(&inAddr,lpaddr,4); // 将获取的地址移动4个字节到inAddr结构中
	int sock, ret = 0, optval = 1;
    struct sockaddr_in sa;
	sa.sin_family = AF_INET;    //用于指定地址格式   
    sa.sin_port = htons(80);  //指定端口,这里htons将80转化为网络字节顺序
    sa.sin_addr.s_addr = inet_addr(inet_ntoa(inAddr));
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	connect(sock, (SOCKADDR*)&sa, sizeof(sa));
	if(sock == -1)
    {
      return(1);
     }
    if(sock == -2)
   {
      return(1);
	}
   ret = send(sock, request, strlen(request), 0);
   int m_nContentLength =1048576 ;
   pageBuf = (char *)malloc(m_nContentLength);
   memset(pageBuf, 0, m_nContentLength);

   int bytesRead = 0;
   while(ret > 0)
   {
       ret = recv(sock, pageBuf + bytesRead, m_nContentLength - bytesRead, 0);
      
      if(ret > 0)
      {
         bytesRead += ret;
      }
   }
	pageBuf[bytesRead] = '\0';
	WSACleanup();
	return(0);
}



int _tmain(int argc, _TCHAR* argv[])
{
    char*  URLcontent;
	UrlSnap("www.hao123.com",URLcontent);
	cout<<URLcontent;

	system("pause");
	return 0;
}
这中间涉及到一点的winsock编程知识,通过gethostbyname来获取地址信息,该函数会返回一个 hostent*类型的指针,其中hostent结构如下
<pre class="cpp" name="code">typedef struct hostent {  
char FAR* h_name;  
char FAR  FAR** h_aliases;  
short h_addrtype;  
short h_length;  
char FAR  FAR** h_addr_list;    //h_addr被定义为该地址列表中的第一个地址,该地址是网络顺序的;
} HOSTENT,  *PHOSTENT,  FAR *LPHOSTENT;


inet_addr 该函数将一个由小数点分割的十进制IP地址字符串转换成由32位二进制数表示的ip地址(网络字节顺序)
 
inet_ntoa 该函数是inet_addr的逆函数,将网络顺序的32位IP地址转换成字符串
in_addr   该结构代表了一个ipv4的网络地址,其字节顺序为网络顺序
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值