如何编程实现:读取一个HTML文件内容并将其中包含的所有IMG文件下载到本地

willzzq 2001-02-21 05:28:00
如何编程实现:
读取一个HTML文件内容并将其中包含的所有IMG文件下载到本地

类似网络蚂蚁、Teleport Pro等工具

我知道这有一定难度本想给高分,可是系统提示最多只能给43分。以后有机会我会加倍回报。
多谢了
...全文
358 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
willzzq 2001-03-05
  • 打赏
  • 举报
回复
Tasehouny, 我正在调试你给的程序,不过有两个问题请教:
是不是先调:HtmlThread() ?
max_level 看来要先找出来?

多谢
wildhorse01 2001-02-24
  • 打赏
  • 举报
回复
用PERL的HTML::TEMPLATE,太简单了!
Tasehouny 2001-02-23
  • 打赏
  • 举报
回复
我这里有一段程序,希望有帮助!!很好用的。

//my_proc.h
#define READ_BUFFER_SIZE 8000
#define DEF_MAX_THREAD 20

#define DTYPE_IMAGE 0
#define DTYPE_ALL 1

#define FTYPE_IMAGE 0
#define FTYPE_HTML 1
#define FTYPE_OTHER 2

#define GTYPE_SAVE 0
#define GTYPE_PROCESS 1


#define DEFAULT_NAME "index.htm"

typedef struct TagProcessHtmlInfo
{
char url[1000];
int level;
int max_level;
} ProcessHtmlInfo;

void SaveURLFile(void *params);
void ProcessHtmlPage(void *params);
void FileThread(void * params);
void HtmlThread(void * params);
int ProcessURL(LPCSTR url,LPSTR server,LPSTR path,LPSTR file);
LPSTR SaveHTML(LPCSTR url);
void SaveFile(LPCSTR url);
void GetAbsURL(LPCSTR page_url,LPSTR tag_url);
int GetURLType(LPCSTR url);
void GetURL(void *params,int type);


//my_proc.cpp

#include "stdafx.h"
#include <process.h>
#include "my_proc.h"


int ThreadNumber=0;
CString CurrentFile;
int MAX_THREAD=DEF_MAX_THREAD;
int DownloadType=DTYPE_IMAGE;


void SaveURLFile(void *params)
{
LPSTR url=(LPSTR)params;
CurrentFile=url;
SaveFile(url);
}


void ProcessHtmlPage(void *params)
{
ProcessHtmlInfo *info=(ProcessHtmlInfo *)params;

if(info->level>=info->max_level) return;

char url[1000];
strcpy(url,info->url);
int level=info->level;

CString tmp=url;
tmp.MakeLower();
if(memcmp(tmp,"http://",7)!=0) return;

//load this page
LPSTR page;
if((page=SaveHTML(url))==NULL)
return;

//save page
if(DownloadType==DTYPE_ALL)
{
char tmp[256];
char file[256];
ProcessURL(url,tmp,tmp,file);
if(file[0]==0)
strcpy(file,DEFAULT_NAME);

FILE *fp;
fp=fopen(file,"wb+");
if(fp!=NULL)
{
fwrite(page,1,strlen(page),fp);
fclose(fp);
}
}

CString PageText=page;
tmp=PageText;
delete page;


//process image files in page
tmp.MakeLower();
int index,i;
while((index=tmp.Find("src="))!=-1)
{
LPSTR file_url=new char[1000];
tmp.SetAt(index,0x20);
i=0;
index+=4;
if(tmp[index]=='\"') index++;

while(tmp[index]!='\"'&&tmp[index]!='>'
&&tmp[index]!=' '&&tmp[index]!=0)
{
file_url[i]=PageText[index];
i++;
index++;
}
file_url[i]=0;

if(strstr(file_url,":")==NULL)
GetAbsURL(url,file_url);

switch(GetURLType(file_url)) {

case FTYPE_IMAGE:
//WaitFileThread();
GetURL((void *)file_url,GTYPE_SAVE);
break;

case FTYPE_HTML:
{
//WaitHTMLThread();
ProcessHtmlInfo *new_info=new ProcessHtmlInfo;
strcpy(new_info->url,file_url);
delete file_url;
new_info->level=level+1;
new_info->max_level=info->max_level;
GetURL((void *)new_info,GTYPE_PROCESS);

break;
}

case FTYPE_OTHER:
//WaitFileThread();
if(DownloadType==DTYPE_ALL)
GetURL((void *)file_url,GTYPE_SAVE);
break;

default:
delete file_url;

}

}

//process links in page
while((index=tmp.Find("href="))!=-1)
{

ProcessHtmlInfo *new_info=new ProcessHtmlInfo;

tmp.SetAt(index,0x20);
i=0;
index+=5;
if(tmp[index]=='\"') index++;

while(tmp[index]!='\"'&&tmp[index]!='>'&&
tmp[index]!=' '&&tmp[index]!=0)
{
new_info->url[i]=PageText[index];
i++;
index++;
}

new_info->url[i]=0;

if(strstr(new_info->url,":")==NULL)
GetAbsURL(url,new_info->url);

new_info->level=level+1;
new_info->max_level=info->max_level;

//get file
switch (GetURLType(new_info->url)) {
case FTYPE_IMAGE:
{
//WaitFileThread();
LPSTR file_url=new char[1000];
strcpy(file_url,new_info->url);
delete new_info;
GetURL((void *)file_url,GTYPE_SAVE);
break;
}

case FTYPE_HTML:
//WaitHTMLThread();
GetURL((void *)new_info,GTYPE_PROCESS);
break;

case FTYPE_OTHER:
if(DownloadType==DTYPE_ALL)
{
//WaitFileThread();
LPSTR file_url=new char[1000];
strcpy(file_url,new_info->url);
delete new_info;
GetURL((void *)file_url,GTYPE_SAVE);
break;
}

default:
delete new_info;
}

}

}


int ProcessURL(LPCSTR url,LPSTR server,LPSTR path,LPSTR file)
{
int type;
int i=0;
CString tmp=url;
tmp.MakeLower();
if(memcmp(tmp,"http://",7)==0)
{
i=7;
type=0;
}
else
return 1;

//set server
int j=0;
while(url[i]!='/'&&url[i]!=0)
{
server[j]=url[i];
j++;
i++;
}

server[j]=0;

if(url[i]==0)
{
strcpy(path,"/");
file[0]=0;
return type;
}

//set path
j=i;
int k=i;
i++;
while(url[i]!=0)
{
if(url[i]=='/') k=i;
i++;
}

memcpy(path,&url[j],k-j+1);
path[k-j+1]=0;

//set file
k++;
strcpy(file,&url[k]);

//return
return type;
}


void SaveFile(LPCSTR url)
{
char server[256];
char path[256];
char file[256];

if(ProcessURL(url,server,path,file)!=0)
return;

if(file[0]==0)
strcpy(file,DEFAULT_NAME);

CSocket socket;
if(!socket.Create()) return;

if(!socket.Connect(server,80))
{
socket.Close();
return;
}

CString tmp;
tmp="GET ";
tmp+=path;
tmp+=file;
tmp+=" HTTP/1.0\r\n\r\n";

if(!socket.Send(tmp,strlen(tmp)))
{
socket.Close();
return;
}

FILE *fp;
fp=fopen(file,"wb+");
if(fp==NULL)
{
socket.Close();
return;
}

char buffer[READ_BUFFER_SIZE];
int count=0;
LPSTR p=NULL;
while((count=socket.Receive(buffer,READ_BUFFER_SIZE-1))!=0)
{
buffer[count]=0;
if((p=strstr(buffer,"\r\n\r\n"))!=NULL)
{
p+=4;
break;
}
else if((p=strstr(buffer,"\n\n"))!=NULL)
{
p+=2;
break;
}
}

count=count-(p-buffer);
fwrite(p,1,count,fp);

while((count=socket.Receive(buffer,READ_BUFFER_SIZE-1))!=0)
fwrite(buffer,1,count,fp);

fclose(fp);
socket.Close();
}


LPSTR SaveHTML(LPCSTR url)
{
char server[256];
char path[256];
char file[256];

if(ProcessURL(url,server,path,file)!=0)
return NULL;

CSocket socket;
if(!socket.Create()) return NULL;

if(!socket.Connect(server,80))
{
socket.Close();
return NULL;
}

CString tmp;
tmp="GET ";
tmp+=path;
tmp+=file;
tmp+=" HTTP/1.0\r\n\r\n";

if(!socket.Send(tmp,strlen(tmp)))
{
socket.Close();
return NULL;
}

char buffer[READ_BUFFER_SIZE];
int count=0;
LPSTR p=NULL;
while((count=socket.Receive(buffer,READ_BUFFER_SIZE-1))!=0)
{
buffer[count]=0;
if((p=strstr(buffer,"\r\n\r\n"))!=NULL)
{
p+=4;
break;
}
else if((p=strstr(buffer,"\n\n"))!=NULL)
{
p+=2;
break;
}
}

tmp=p;

while((count=socket.Receive(buffer,READ_BUFFER_SIZE-1))!=0)
{
buffer[count]=0;
tmp+=buffer;
}

socket.Close();

int length=tmp.GetLength();
LPSTR page=new char[length+1];

strcpy(page,tmp);
return page;
}


void GetAbsURL(LPCSTR page_url,LPSTR tag_url)
{
char server[256];
char path[256];
char file[256];

ProcessURL(page_url,server,path,file);

CString tmp="http://";
tmp+=server;
if(tag_url[0]!='/')
tmp+=path;
tmp+=tag_url;

strcpy(tag_url,tmp);

return;

}

int GetURLType(LPCSTR url)
{
CString tmp=url;
tmp.MakeLower();
if(tmp.Find(".jpg")!=-1||tmp.Find(".gif")!=-1||tmp.Find(".jpeg")!=-1)
return FTYPE_IMAGE;
else if(tmp.Find(".htm")!=-1||tmp.Find(".html")!=-1||tmp.Find(".")==-1)
return FTYPE_HTML;
else
return FTYPE_OTHER;
}


void FileThread(void * params)
{
//ThreadNumber++;
LPSTR url=(LPSTR)params;
SaveURLFile((void *)url);
delete url;
ThreadNumber--;
}

void HtmlThread(void * params)
{
//ThreadNumber++;

ProcessHtmlInfo *info=(ProcessHtmlInfo *)params;

ProcessHtmlPage((void *)info);

delete info;
ThreadNumber--;
}

void GetURL(void *params,int type)
{
switch(type) {
case GTYPE_SAVE:
if(ThreadNumber>=MAX_THREAD)
{
SaveURLFile(params);
delete params;
}
else
{
ThreadNumber++;
_beginthread(FileThread,0,params);
}
break;

case GTYPE_PROCESS:
if(ThreadNumber>=MAX_THREAD)
{
ProcessHtmlPage(params);
delete params;
}
else
{
ThreadNumber++;
_beginthread(HtmlThread,0,params);
}
break;
}
}





/*
void WaitFileThread()
{

while(FileThreadNumber>MAX_THREAD/2)
{
int time=(int)((float)rand()/RAND_MAX)*200;
Sleep(time);
}

FileThreadNumber++;
return;
}

void WaitHTMLThread()
{
while(HTMLThreadNumber>MAX_THREAD/2)
{
int time=(int)((float)rand()/RAND_MAX)*200;
Sleep(time);
}
HTMLThreadNumber++;
return;
}*/


willzzq 2001-02-23
  • 打赏
  • 举报
回复
我在VID里可以用ADODB.Stream,是2.5版(在注册表里可以查到).
只是不知道它到底可以实现什么功能,那些接口如何按序调用.
应该是与数据库有关的. 好像与文件存储没有太大的关系.
wingc, 你真是热心人,我这厢有礼了!
wingc 2001-02-23
  • 打赏
  • 举报
回复
呵呵,我找到了,不过在我的98上注册不了。
willzzq 2001-02-23
  • 打赏
  • 举报
回复
我用的是Win2000
ctxiaocai 2001-02-23
  • 打赏
  • 举报
回复
老周,这个问题好深奥的说,
有机会向你请教,呵呵
wingc 2001-02-23
  • 打赏
  • 举报
回复
www.aspcn.com有源代码的上传组件,存二进制文件的代码在里面,可以参考一下。
不用那么客气啊,我是只是觉得我以前不负责任的向你推荐adodb.stream实在是对不起。
你用的是windows什么版?我得想办法把ADO 2.5装上。
willzzq 2001-02-23
  • 打赏
  • 举报
回复
顺便说一下,ADODB 2.5 (c:\program file\common files\system\ado\msado15.dll) 无法在NT Server 4.0 中注册

恐怕要用第三方组件,不知哪儿有?
willzzq 2001-02-23
  • 打赏
  • 举报
回复
顺便说一下,ADODB 2.5 (c:\program file\common files\system\ado\msado15.dll) 无法在NT Server 4.0 中注册

恐怕要用第三方组件,不知哪儿有?
willzzq 2001-02-22
  • 打赏
  • 举报
回复
wingc 2001-02-22
  • 打赏
  • 举报
回复
http://www.csdn.net/expert/TopicView.asp?id=63333
找到了,是这篇帖子,原来他用的是ADO2.5,看来你得找到ADO2.5再用了。
我的机器上是ADO2.1,也用不了ADODB.Stream.
wingc 2001-02-22
  • 打赏
  • 举报
回复
我很抱歉,我向你推荐ADODB.Stream,实际上我也是看了人家的文章,自己没有实践过,看到你想找ADODB.Stream的帮助,我就去找了找。在VB的对象浏览器里发现ADO2.0里没有ADODB.Stream这个对象,真是奇怪,难道我看那篇文章里作者用的是ADO3.0!(这个东东估计目前还没有)所以我感到万分抱歉,用其它组件吧。
我想办法把以前那篇文章找到,自己再研究研究,对不起。
willzzq 2001-02-22
  • 打赏
  • 举报
回复
多谢多谢
不知道哪有有关 ADODB.Stream 的帮助
我在VID下试了好多次,因不知道诸多接口的调用顺序而未果
请不吝赐教
Itboy 2001-02-22
  • 打赏
  • 举报
回复
到VB版看看
wingc 2001-02-22
  • 打赏
  • 举报
回复
http://www.csdn.net/expert/TopicView.asp?id=69741
看看这篇帖子itboy的回答就应该知道如何抓取文件。
分析出img的src就要你看你自己的程序了。
至于将抓来的图片存下来要是不用第三方组件的话,就试试ADODB.Stream这个对象吧。

28,406

社区成员

发帖
与我相关
我的任务
社区描述
ASP即Active Server Pages,是Microsoft公司开发的服务器端脚本环境。
社区管理员
  • ASP
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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