#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//提示信息
void Help(char * str)
{
printf("/n%s/t<StartNum>/t[EndNum]/n",str);
printf("StartNum/t开始ID号;/n");
printf("EndNum/t/t结束ID号,默认为开始号+100;/n");
}
////////////////////////////////////////////////////////////////////////
//
// 函数名:GetWebImg()
// 说明:从WEB上下载图片,保存到data/中
// 参数:(char *)imgurl 图片地址
// (char *)imgname 保存到本地的图片名称
// 返回:(int)0 图片成功下载
//
///////////////////////////////////////////////////////////////////////
int GetWebImg( char * imgurl,char * imgname)
{
WSADATA wsd;
SOCKET sClient;
char szBuffer[1024];
char szServer[128];
char CurrentPath[256];
char FilePath[256];
int ret,i,iPort;
struct sockaddr_in server;
struct hostent * host=NULL;
FILE *fp;
memset(szBuffer,0,sizeof(szBuffer));
GetCurrentDirectory(sizeof(CurrentPath),CurrentPath);
strcat(CurrentPath,"//");
strcpy(FilePath,CurrentPath);
strcat(FilePath,"//img//");
strcat(FilePath,imgname);
if((fp=fopen(FilePath,"wb"))==NULL)
{
printf("file can not open!/n");
exit(0);
}
//发送给远程主机的请求内容串
sprintf(szBuffer,
"GET %s HTTP/1.1/r/nHost:%s/r/nConnection:Close/r/n/r/n",imgurl,HOST);
iPort=80;
// printf("buf:%s/n%d/n",szBuffer,strlen(szBuffer));
memset(szServer,0,sizeof(szServer));
sprintf(szServer,"bookcity.dayoo.com");
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)
{
printf("Failed to load Winsock library!/n");
return -1;
}
sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sClient==INVALID_SOCKET)
{
printf("socket() failed:%d/n",WSAGetLastError());
return -1;
}
server.sin_family=AF_INET;
server.sin_port=htons(iPort);
server.sin_addr.s_addr=inet_addr(szServer);
if(server.sin_addr.s_addr==INADDR_NONE)
{
host=gethostbyname(szServer);
if(host==NULL)
{
printf("Unable to resolve server: %s/n",
szServer);
return -1;
}
CopyMemory(&server.sin_addr,host->h_addr_list[0],
host->h_length);
}
if(connect(sClient,(struct sockaddr *)&server,
sizeof(server))==SOCKET_ERROR)
{
printf("connect() failed: %d/n",WSAGetLastError());
return -1;
}
//发送
ret=send(sClient,szBuffer,strlen(szBuffer),0);
if(ret==0 || ret==SOCKET_ERROR)
{
printf("send() failed: %d/n",WSAGetLastError());
return -1;
}
// printf("send %d/n",ret);
int ok=0;
int it=0;
int count=1;
char * tmp;
//接收
while(1)
{
memset(szBuffer,0,sizeof(szBuffer));
ret=0;
ret=recv(sClient,szBuffer,sizeof(szBuffer),0);
if(ret==0)
{
break;
}
if(count>0)
{
//在第一个接收到的数据中查第一个空格后是响映号码200为正确
for(tmp=szBuffer;*tmp!='/0'&&!isspace(*tmp);++tmp)
;
for(;isspace(*tmp);++tmp)
;
ok=atoi(tmp);
for(;strnicmp(tmp,"/r/n/r/n",4);++tmp)
;
tmp=tmp+4; //去除实体头
it=(int)(tmp-szBuffer);
it=(int)(ret-it);
fwrite(tmp,sizeof(char),it,fp);
count=0;
}
else
{
it=it+ret;
fwrite(szBuffer,sizeof(char),ret,fp);
}
// printf("%s/n",szBuffer);
}
// printf("%d/n",it);
printf("/nget %s file full!/n",imgurl);
fclose(fp);
closesocket(sClient);
WSACleanup();
return 0;
}
//////////////////////////////////////////////////////////////////////
//
// 函数名:GetHTMLData()
//
// 说明:从HTML字符串中取出所需要的数据(如:<span id="ddd">xxxxx</span>
//
// 参数:
// (char *)tag 数据所在的HTML标签名
// (char *)Id 标签ID值
// (char *)html HTML字串(文件区),在这里面找出我需要的数据
// (char *)data 找到数据存放的区域,输出
// (int)size data的大小
//
// 返回:(int) 0找到数据
//
// 错语:返回-1为没找到数据.
//
/////////////////////////////////////////////////////////////////////
int GetHTMLData(char * tag,char * Id,char *html,char * data,int size)
{
char ltag[256],tmptag[256],lid[256],tmplid[256],*lhtml,*tmp,*fortmp;
char* start;//数据开始位置
int n,count;//计数器
strcpy(ltag,tag);
strcpy(lid,Id);
///原理
//1,找到第一个ID=id的tag标签然后计数器加1,
//循环下面两步
//2,检查计数器,如果计数器==0表明操作完成
//3,从ID=id的tag标签处开始找配对标签出栈和新的(钳套标签)入栈
////////////////////////////////////////////////////////////////
//第一步找到第一个ID=id的tag
for(fortmp=html;fortmp<(html+strlen(html));fortmp++)
{
n=100;
memset(tmptag,0,sizeof(tmptag));
sprintf(tmptag,"<%s",ltag);
if(strnicmp(fortmp,tmptag,strlen(tmptag))==0)
{
//从第一个tag标签到">"处找ID=id的值是否存在
for(tmp=fortmp;tmp<(fortmp+strlen(fortmp));tmp++)
{
memset(tmplid,0,sizeof(tmplid));
sprintf(tmplid,"id=/"%s/"",lid);
if(strnicmp(tmp,tmplid,strlen(tmplid))==0)
{
//找到ID=id的标签,进入第二步
n=0;
//break;
}
if(n==0)
{
if(strnicmp(tmp,">",strlen(">"))==0)
{
//继续找下一个tag
fortmp=tmp;
break;
}
}
}
}
if(n==0)
break;
}
//找不到tag和id一样的标签
if(n!=0)
{
memset(data,0,size);
return -1;
}
count=1;
start=fortmp+1;//保存数据开始位置
/////////////////////////////////////////////第二步
//2,检查栈指针是否在栈底,如果在栈底就完成查栈
//3,从ID=id的tag标签处开始找配对标签出栈和新的(钳套标签)入栈
tmp=fortmp;
for(fortmp;fortmp<tmp+strlen(tmp);fortmp++)
{
memset(tmptag,0,sizeof(tmptag));
sprintf(tmptag,"<%s",ltag);
if(strnicmp(fortmp,tmptag,strlen(tmptag))==0)
{
//有钳套标签,count+1
count++;
}
memset(tmptag,0,sizeof(tmptag));
sprintf(tmptag,"</%s>",ltag);
if(strnicmp(fortmp,tmptag,strlen(tmptag))==0)
{
//找到一个结束的标签,count--
count--;
}
if(count<1)
{
break;
}
}
//start[300]='/0';
//printf("%s/n",start);
memset(data,0,size);
n=fortmp-start;
if(n>size-1)
{
n=size-1;
}
// strncpy(data,start,n);
memcpy(data,start,n);
data[n]='/0';
return 0;
}
//////////////////////////////////////////////////////////////////////
//
// 函数名:GetImgUrl()
//
// 说明:从HTML字符串中取出所需要的图像URL
//
// 参数:
// (char *)Id 标签ID值
// (char *)html HTML字串(文件区),在这里面找出我需要的数据
// (char *)data 找到数据存放的区域,输出
// (int)size data的大小
//
// 返回:(int) 0找到数据
//
// 错语:返回-1为没找到数据.
//
/////////////////////////////////////////////////////////////////////
int GetImgUrl(char * Id,char *html,char * data,int size)
{
char ltag[256],tmptag[256],lid[256],tmplid[256],*lhtml,*tmp,*fortmp;
char* start;//数据开始位置
int n,count;//计数器
strcpy(ltag,"img");
strcpy(lid,Id);
////////////////////////////////////////////////////////////////
//第一步找到第一个ID=id的tag
for(fortmp=html;fortmp<(html+strlen(html));fortmp++)
{
n=100;
memset(tmptag,0,sizeof(tmptag));
sprintf(tmptag,"<%s",ltag);
if(strnicmp(fortmp,tmptag,strlen(tmptag))==0)
{
//从第一个tag标签到">"处找ID=id的值是否存在
for(tmp=fortmp;tmp+strlen(fortmp);tmp++)
{
memset(tmplid,0,sizeof(tmplid));
sprintf(tmplid,"id=/"%s/"",lid);
if(strnicmp(tmp,tmplid,strlen(tmplid))==0)
{
//找到ID=id的标签,进入第二步
start=fortmp;
n=0;
//break;
}
if(strnicmp(tmp,">",strlen(">"))==0)
{
fortmp=tmp;
break;
}
}
}
if(n==0)
break;
}
//找不到tag和id一样的标签
if(n!=0)
{
return -1;
}
fortmp=start;//保存ID=我们ID的<img的位置
start=tmp;//保存/>的位置
/////////////////////////////////////////////第二步
//3,从<img处到/>找 src=
tmp=fortmp;
// fortmp[30]='/0';
// printf("%s/n",fortmp);
char *tp,*tp2;
for(fortmp;fortmp<start;fortmp++)
{
memset(tmptag,0,sizeof(tmptag));
sprintf(tmptag,"src=");
if(strnicmp(fortmp,tmptag,strlen(tmptag))==0)
{
tp=fortmp+strlen("str=");//记下数据的开始位置
tp2=strstr(fortmp," ");
tp[tp2-tp]='/0';
//printf("%s/n",tp);
break;
}
}
memset(data,0,size);
strcpy(data,tp);
return 0;
}
/* 函数:GetBooks
* 描述:从网上抓取网页数据存到全局szHtml中
* 参数:网址 ID
* 返回:0完成
*/
int GetBooks(char * url,int id)
{
char lurl[256],szTmp[256],szTemp[256],*pszTmp,*pszMake,*pszBuf;
sprintf(lurl,"%s%d/0",url,id);
printf("%s/n",lurl);
WSADATA wsd;
SOCKET sClient;
char szBuffer[1024];
char szServer[128];
int ret,i,iPort,itmp,pszTmpSize;
struct sockaddr_in server;
struct hostent * host=NULL;
FILE *fp;
memset(szBuffer,0,sizeof(szBuffer));
//发送给远程主机的请求内容串
sprintf(szBuffer,
"GET %s HTTP/1.1/r/nAccept-Language:zh-cn/r/nHost:%s/r/nConnection:Close/r/n/r/n",
lurl,HOST);
iPort=80;
memset(szServer,0,sizeof(szServer));
sprintf(szServer,"bookcity.dayoo.com");
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)
{
printf("Failed to load Winsock library!/n");
return -1;
}
sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sClient==INVALID_SOCKET)
{
printf("socket() failed:%d/n",WSAGetLastError());
return -1;
}
server.sin_family=AF_INET;
server.sin_port=htons(iPort);
server.sin_addr.s_addr=inet_addr(szServer);
if(server.sin_addr.s_addr==INADDR_NONE)
{
host=gethostbyname(szServer);
if(host==NULL)
{
printf("Unable to resolve server: %s/n",
szServer);
return -1;
}
CopyMemory(&server.sin_addr,host->h_addr_list[0],
host->h_length);
}
if(connect(sClient,(struct sockaddr *)&server,
sizeof(server))==SOCKET_ERROR)
{
printf("connect() failed: %d/n",WSAGetLastError());
return -1;
}
sprintf(szBuffer,
"HEAD %s HTTP/1.1/r/nAccept-Language:zh-cn/r/nHost:%s/r/n/r/n",
lurl,HOST);
//发送
ret=send(sClient,szBuffer,strlen(szBuffer),0);
if(ret==0 || ret==SOCKET_ERROR)
{
printf("send() failed: %d/n",WSAGetLastError());
return -1;
}
//接收头文件
ret=recv(sClient,szBuffer,sizeof(szBuffer)-1,0);
szBuffer[ret]='/0';
//输入响映代码头
for(i=0;szBuffer[i]!='/0'&&strnicmp(&szBuffer[i],"/r/n",2);i++)
;
memset(szTmp,0,sizeof(szTmp));
strncpy(szTmp,szBuffer,i);
printf("%s/n",szTmp);
//判别响映代码
for(i=0;szBuffer[i]!='/0'&&!isspace(szBuffer[i]);i++)
;
for(;isspace(szBuffer[i]);i++)
;
itmp=atoi(&szBuffer[i]);
//printf("%d/n",itmp);
if(itmp!=200)
return -1;
//获取实体长度
for(i=0;szBuffer[i]!='/0'&&strnicmp(&szBuffer[i],"Content-Length:",15);i++)
;
i=i+15;
itmp=atoi(&szBuffer[i]);
//printf("%d/n",itmp);
pszTmpSize=itmp+1;
pszTmp=(char*)malloc(sizeof(char)*pszTmpSize);
pszMake=(char*)malloc(sizeof(char)*pszTmpSize);
pszBuf=(char*)malloc(sizeof(char)*pszTmpSize);
if(pszTmp==NULL||pszMake==NULL||pszBuf==NULL)
{
printf("动态内存分配失败!/n");
return -1;
}
memset(szBuffer,0,sizeof(szBuffer));
sprintf(szBuffer,
"GET %s HTTP/1.1/r/nAccept-Language:zh-cn/r/nHost:%s/r/nConnection:Close/r/n/r/n",
lurl,HOST);
//发送
ret=send(sClient,szBuffer,strlen(szBuffer),0);
if(ret==0 || ret==SOCKET_ERROR)
{
printf("send() failed: %d/n",WSAGetLastError());
return -1;
}
//printf("%d/n",ret);
memset(szBuffer,0,sizeof(szBuffer));
ret=recv(sClient,szBuffer,sizeof(szBuffer)-1,0);
for(i=0;szBuffer[i]!='/0'&&strnicmp(&szBuffer[i],"/r/n/r/n",4);i++)
;
i=i+4;
itmp=ret-i;
int cn=0; //计数
memset(pszTmp,0,pszTmpSize);
memcpy(&pszTmp[cn],&szBuffer[i],itmp);
cn=cn+itmp;
while(1)
{
memset(szBuffer,0,sizeof(szBuffer));
ret=0;
ret=recv(sClient,szBuffer,sizeof(szBuffer)-1,0);
if(ret==0)
{
break;
}
memcpy(&pszTmp[cn],szBuffer,ret);
cn=ret+cn;
}
pszTmp[cn]='/0';
// printf("%s/n",pszTmp);
///////////////////////////////////////////////调用数据分析函数
/*
memset(pszBuf,0,sizeof(char)*pszTmpSize);
//编号
sprintf(pszBuf,"%d",id);
//图书名称<span id="Labelname"></span>
memset(pszMake,0,sizeof(char)*pszTmpSize);
GetHTMLData("span","Labelname",pszTmp,pszMake,sizeof(char)*pszTmpSize);
//printf("%s/n",pszMake);
strcat(pszBuf,",/"");
strcat(pszBuf,pszMake);
strcat(pszBuf,"/"");
//作者<a id="Bookinfomodule1_HyperLinkWriter">这里是作者名</a>
memset(pszMake,0,sizeof(char)*pszTmpSize);
GetHTMLData("a","Bookinfomodule1_HyperLinkWriter",
pszTmp,pszMake,sizeof(char)*pszTmpSize);
strcat(pszBuf,",/"");
strcat(pszBuf,pszMake);
strcat(pszBuf,"/"");
//取出ISBN:<span id="Bookinfomodule1_LabelIsdn">7500666934</span>
memset(pszMake,0,sizeof(char)*pszTmpSize);
GetHTMLData("span","Bookinfomodule1_LabelIsdn",
pszTmp,pszMake,sizeof(char)*pszTmpSize);
strcat(pszBuf,",/"");
strcat(pszBuf,pszMake);
strcat(pszBuf,"/"");
//出版社<a id="Bookinfomodule1_HyperLinkPublishName"></a>
memset(pszMake,0,sizeof(char)*pszTmpSize);
GetHTMLData("a","Bookinfomodule1_HyperLinkPublishName",
pszTmp,pszMake,sizeof(char)*pszTmpSize);
strcat(pszBuf,",/"");
strcat(pszBuf,pszMake);
strcat(pszBuf,"/"");
//原价<span id="Bookinfomodule1_LabelPrice1"></span>
memset(pszMake,0,sizeof(char)*pszTmpSize);
GetHTMLData("span","Bookinfomodule1_LabelPrice1",
pszTmp,pszMake,sizeof(char)*pszTmpSize);
strcat(pszBuf,",");
strcat(pszBuf,"/"");
strcat(pszBuf,&pszMake[2]);//跳过两个字节,美元的符号
strcat(pszBuf,"/"");
/////////////////////////////////////////内容<span id="LabelDescription"></span>
memset(pszMake,0,sizeof(char)*pszTmpSize);
GetHTMLData("span","LabelDescription",
pszTmp,pszMake,sizeof(char)*pszTmpSize);
strcat(pszBuf,",/"");
//////////////////////////去除tmpBuf中的'/r'回车符
char *t,*t2;
t=(char*)malloc(sizeof(char)*pszTmpSize);
t2=(char*)malloc(sizeof(char)*pszTmpSize);
memcpy(t,pszMake,sizeof(char)*pszTmpSize);
memset(pszMake,0,sizeof(char)*pszTmpSize);
for(;;t=NULL)
{
if((t2=strtok(t,"/r"))==NULL) break;
strcat(pszMake,t2);
}
free(t);
free(t2);
/////////////////////////////去除"/r"结束
//access规则把所有"变成""
t=(char*)malloc(sizeof(char)*pszTmpSize);
t2=(char*)malloc(sizeof(char)*pszTmpSize);
memcpy(t,pszMake,sizeof(char)*pszTmpSize);
memset(pszMake,0,sizeof(char)*pszTmpSize);
for(;;t=NULL)
{
if((t2=strtok(t,"/""))==NULL) break;
strcat(pszMake,t2);
strcat(pszMake,"/"/"");
}
pszMake[strlen(pszMake)-strlen("/"/"")]='/0';
free(t);
free(t2);
/////////////////////
strcat(pszBuf,pszMake);
strcat(pszBuf,"/"");
///////////////////////////////////////////////////////////内容完成
/*
//////////////////////////////////////////////////////////图片处理部分
//<img id="Bookimg" src="xxxxxxxx.jpg" />
memset(pszMake,0,sizeof(char)*pszTmpSize);
GetImgUrl("Bookimg",pszTmp,pszMake,sizeof(char)*pszTmpSize);
memset(szTmp,0,sizeof(szTmp));
strcpy(szTmp,URL);
for(i=strlen(szTmp)-1;i>0;i--)//去除URL后面的/之后的文件名部份
{
if(szTmp[i]=='/')
{
szTmp[i]='/0';
break;
}
}
strcat(szTmp,"/");
pszMake[strlen(pszMake)-1]='/0';//去除双引号
strcat(szTmp,&pszMake[1]);
strcpy(pszMake,szTmp);
strcpy(szTmp,&pszMake[strlen(pszMake)-3]);//获取图片的扩展名
//重新生成图片的名称
time_t tt;
struct tm * now;
tt=time(NULL);
now=localtime(&tt);
strftime(szTemp,sizeof(szTemp),"%Y%m%d%H%M%s",now);
strcat(szTemp,".");
strcat(szTemp,szTmp);
strcat(pszBuf,",/"");
strcat(pszBuf,szTemp);
strcat(pszBuf,"/"");
//从网上下载图片
//如果图片名是nocover.gif就不下载,这个是没有图片的意思
if((strstr(pszMake,"nocover.gif"))==NULL)
{
if(GetWebImg(pszMake,szTemp)!=0) return -1;
}
//printf("%s/n",pszBuf);*/
///////////////////////////////////////////////////////////////写到文本文件
if((fp=fopen("data.txt","a"))==NULL)
{
printf("打开文件失败!/n");
return -1;
}
fprintf(fp,"%s/n",pszBuf);
fclose(fp);
/////////////////////////////////////////////////////////////写文件完成
///////////////////////////////////////////////////获取数据完成
free(pszMake);
free(pszTmp);
closesocket(sClient);
WSACleanup();
return 0;
}