菜鸟挤的代码,弄了几天几夜,现在都不知道该怎么通过编译了,请大家帮帮忙。

tianjiao85 2008-04-19 09:39:45
使用的是VS 2005,自己理解爬虫程序,想写个程序,没想到耗了我好几天精力,没这办法了,请大侠们解救。
我理解爬虫程序:
e1.连接第一个服务器,先下载好一个网页数据,保存在recvBuf,继续e2
e2.从recvBuf提取http链接,存入到 web(类型map<char *,vector<char *>>),char *段用来存储服务器也就是网站主机域名,vector<char *>>用来存储这个网站的http链接,继续e3。
e3.下载该站点下下一个网页(也就是存放在map类型中的vector<char *>段的链接),继续e2。
e4,重复e3,当第一个站点下所有http链接都完成下载,访问下个服务器,继续e1。
e5. 保存到硬盘。

每次执行e2时,遇到新的服务器,都会在web中添加一个pair<char *,vector<char *>>,既是服务器和它的网页。

程序现在没有考虑的有:
爬虫的思路的正确性
爬的层数
存储,
效率。,等,
代码只要能够运行起来,电脑爆了了也没关系,就是要验证想法,解决完这个问题后,才考虑其他问题。
所以先请大侠们,帮我看看代码,提提修改建议,
之后,欢迎大家讨论,批评,小弟一定细细聆听。
考虑到代码的可读性不好,本次发帖给分给满分,有劳各位大侠们。

#include <WinSock2.h>
#include <cstring>
#include <vector>
#include <fstream>
#include <map>
#include <iostream>
#include <boost/regex.hpp>
using namespace std;

map<char *,vector<char *>> web;

char recvBuf[1024*200+1] = {0}; //接收缓冲区
char sendBuff[200] = "GET "; //发送缓冲区
char *str = "http://(\w+\.\w+\.\w+)(/\w+)*(/\w+\.\w){1}";
boost::basic_regex<char> regStr(str);//查找http的正则表达式
boost::cmatch httpSet; //保存匹配的http

bool connectServ(const char *);//连接服务器,并下载网页
void getPage(char *server,
char * http,
SOCKET &sockClient,
map<char *,vector<char *>> &web); // 下载网页

int main(int argc, char **argv)
{
ofstream outFile;
char * const index="www.hnu.cn";
web[index].push_back("http://www.hnu.cn/");
map<char *,vector<char *>>::iterator map_It = web.begin();
for (;map_It != web.end();map_It++)
{
//从map对象中读取服务器和网址进行访问
connectServ(map_It->first);
}

outFile.open("http.txt",ios::out|ios::app);
for (;map_It != web.end();map_It++)
{
outFile<<"Server: "<<map_It->first<<endl;
vector<char *>::iterator beg_it = map_It->second.begin();
vector<char *>::iterator end_it = map_It->second.end();
for (;beg_it != end_it; beg_it++)
{
//打印服务器下所有网址
outFile<<*beg_it<<endl;
}
}
return 0;
}

bool connectServ(char * const &server)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return false;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return false;
}

SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;



hostent* remoteHost;
char * const host_name= server;
unsigned int addr;
if (isalpha(host_name[0]))
{ /* host address is a name */
if (host_name[strlen(host_name)-1] == '\n')
host_name[strlen(host_name)-1] = '\0';
remoteHost = gethostbyname(host_name);
}
else
{
addr = inet_addr(host_name);
remoteHost = gethostbyaddr((char *)&addr, 4, AF_INET);
}

memcpy(&addrSrv.sin_addr.S_un.S_addr,remoteHost->h_addr,remoteHost->h_length);
if (WSAGetLastError() != 0)
{
if (WSAGetLastError() == 11001)
printf("Host not found...\nExiting.\n");
}
else
printf("error#:%ld\n", WSAGetLastError());

addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(80);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
vector<char *>::iterator iter = web[server].begin();
for (;iter != web[server].end();iter++)
{
//下载一个服务器上的网页
getPage(server, *iter,sockClient,web);
}


closesocket(sockClient);
WSACleanup();
cout<<"getPage success!"<<endl;

}

void getPage(char *server,char * http,SOCKET &sockClient,map<char *,vector<char *>> &web)
{
//http消息格式
strcpy(sendBuff,http);
strcpy(sendBuff," HTTP/1.0\r\nHost:");
strcpy(sendBuff,server);
strcpy(sendBuff,"\r\n\r\n");
send(sockClient,sendBuff,strlen(sendBuff),0);

int cc;
cc=recv(sockClient,recvBuf,1024*200,0);
char * tempBuf = recvBuf;
while(cc!=SOCKET_ERROR&&cc>0)
{
//循环下载网页数据并保存到map
while (boost::regex_search(tempBuf,httpSet,regStr))
{
string temp(httpSet[0].first,httpSet[0].second);
web[server].push_back(const_cast<char *>(temp.c_str()));
tempBuf = const_cast<char *>(httpSet[0].second);
}
cc=recv(sockClient,recvBuf,1024*200,0);
}
}

...全文
881 52 打赏 收藏 转发到动态 举报
写回复
用AI写文章
52 条回复
切换为时间正序
请发表友善的回复…
发表回复
sybil1110000 2012-07-27
  • 打赏
  • 举报
回复
mark
chengziyu 2010-07-24
  • 打赏
  • 举报
回复
我也遇到这个问题了
tianjiao85 2008-04-22
  • 打赏
  • 举报
回复

#include <WinSock2.h>
#include <cstring>
#include <vector>
#include <fstream>
#include <map>
#include <iostream>
#include <boost/regex.hpp>
using namespace std;

#pragma comment( lib , "ws2_32.lib")

map<char *,vector<char *> > web;

char recvBuf[1024*200+1] = {0}; //接收缓冲区
char sendBuff[200] = "GET "; //发送缓冲区
char *str = "http://(\\w+\\.\\w+\\.\\w+)(/\\w+)*(/\\w+\\.\\w){1}";
boost::basic_regex<char> regStr(str);//查找http的正则表达式
boost::cmatch httpSet; //保存匹配的http

void connectServ(char * const &server);//连接服务器,并下载网页
void getPage(char *const &server,
char * http,
SOCKET &sockClient,
map<char *,vector<char *> > &web); // 下载网页

ofstream outFile;


int main(int argc, char **argv)
{
outFile.open("http.txt",ios::out|ios::app);
char * const index="www.hnu.cn";
web[index].push_back("http://www.hnu.cn/");
map<char *,vector<char *> >::iterator map_It = web.begin();
for (;map_It != web.end();map_It++)
{
//从map对象中读取服务器和网址进行访问
connectServ(map_It->first);
}


for (;map_It != web.end();map_It++)
{
outFile<<"Server: "<<map_It->first<<endl;
vector<char *>::iterator beg_it = map_It->second.begin();
vector<char *>::iterator end_it = map_It->second.end();
for (;beg_it != end_it; beg_it++)
{
//打印服务器下所有网址
outFile<<*beg_it<<endl;
}
}
return 0;
}

void connectServ(char * const &server)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}

SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;



hostent* remoteHost;
char * const host_name= server;
unsigned int addr;
if (isalpha(host_name[0]))
{ /* host address is a name */
if (host_name[strlen(host_name)-1] == '\n')
host_name[strlen(host_name)-1] = '\0';
remoteHost = gethostbyname(host_name);
}
else
{
addr = inet_addr(host_name);
remoteHost = gethostbyaddr((char *)&addr, 4, AF_INET);
}

::memcpy(&addrSrv.sin_addr.S_un.S_addr,remoteHost->h_addr,remoteHost->h_length);
if (WSAGetLastError() != 0)
{
if (WSAGetLastError() == 11001)
printf("Host not found...\nExiting.\n");
}
else
printf("error#:%ld\n", WSAGetLastError());

addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(80);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
vector<char *>::iterator iter = web[server].begin();
for (;iter != web[server].end();iter++)
{
//下载一个服务器上的网页
getPage(server, *iter,sockClient,web);
}


closesocket(sockClient);
WSACleanup();
cout<<"getPage success!"<<endl;

}

void getPage(char *const &server,char * http,SOCKET &sockClient,map<char *,vector<char *> > &web)
{
//http消息格式
::strcat(sendBuff,http);
::strcat(sendBuff," HTTP/1.0\r\nHost:");
::strcat(sendBuff,server);
::strcat(sendBuff,"\r\n\r\n");
send(sockClient,sendBuff,strlen(sendBuff),0);

int cc;
cc=recv(sockClient,recvBuf,1024*200,0);
char * tempBuf = recvBuf;
while(cc!=SOCKET_ERROR&&cc>0)
{
//循环下载网页数据并保存到map
while (boost::regex_search(tempBuf,httpSet,regStr))
{
string templink(httpSet[0].first,httpSet[0].second);//保存超链接
string tempserver(httpSet[1].first,httpSet[1].second);
char *const server = const_cast<char *>(tempserver.c_str());
web[server].push_back(const_cast<char *>(templink.c_str()));
tempBuf = const_cast<char *>(httpSet[0].second);
outFile<<tempserver<<endl;
outFile<<templink<<endl;
}
cc=recv(sockClient,recvBuf,1024*200,0);
}
}
tianjiao85 2008-04-22
  • 打赏
  • 举报
回复
#include <WinSock2.h>
#include <cstring>
#include <vector>
#include <fstream>
#include <map>
#include <iostream>
#include <boost/regex.hpp>
using namespace std;

#pragma comment( lib , "ws2_32.lib")

map<char *,vector<char *> > web;

char recvBuf[1024*200+1] = {0}; //接收缓冲区
char sendBuff[200] = "GET "; //发送缓冲区
char *str = "http://(\\w+\\.\\w+\\.\\w+)(/\\w+)*(/\\w+\\.\\w){1}";
boost::basic_regex<char> regStr(str);//查找http的正则表达式
boost::cmatch httpSet; //保存匹配的http

void connectServ(char * const &server);//连接服务器,并下载网页
void getPage(char *const &server,
char * http,
SOCKET &sockClient,
map<char *,vector<char *> > &web); // 下载网页

ofstream outFile;


int main(int argc, char **argv)
{
outFile.open("http.txt",ios::out|ios::app);
char * const index="www.hnu.cn";
web[index].push_back("http://www.hnu.cn/");
map<char *,vector<char *> >::iterator map_It = web.begin();
for (;map_It != web.end();map_It++)
{
//从map对象中读取服务器和网址进行访问
connectServ(map_It->first);
}


for (;map_It != web.end();map_It++)
{
outFile<<"Server: "<<map_It->first<<endl;
vector<char *>::iterator beg_it = map_It->second.begin();
vector<char *>::iterator end_it = map_It->second.end();
for (;beg_it != end_it; beg_it++)
{
//打印服务器下所有网址
outFile<<*beg_it<<endl;
}
}
return 0;
}

void connectServ(char * const &server)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}

SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;



hostent* remoteHost;
char * const host_name= server;
unsigned int addr;
if (isalpha(host_name[0]))
{ /* host address is a name */
if (host_name[strlen(host_name)-1] == '\n')
host_name[strlen(host_name)-1] = '\0';
remoteHost = gethostbyname(host_name);
}
else
{
addr = inet_addr(host_name);
remoteHost = gethostbyaddr((char *)&addr, 4, AF_INET);
}

::memcpy(&addrSrv.sin_addr.S_un.S_addr,remoteHost->h_addr,remoteHost->h_length);
if (WSAGetLastError() != 0)
{
if (WSAGetLastError() == 11001)
printf("Host not found...\nExiting.\n");
}
else
printf("error#:%ld\n", WSAGetLastError());

addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(80);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
vector<char *>::iterator iter = web[server].begin();
for (;iter != web[server].end();iter++)
{
//下载一个服务器上的网页
getPage(server, *iter,sockClient,web);
}


closesocket(sockClient);
WSACleanup();
cout<<"getPage success!"<<endl;

}

void getPage(char *const &server,char * http,SOCKET &sockClient,map<char *,vector<char *> > &web)
{
//http消息格式
::strcat(sendBuff,http);
::strcat(sendBuff," HTTP/1.0\r\nHost:");
::strcat(sendBuff,server);
::strcat(sendBuff,"\r\n\r\n");
send(sockClient,sendBuff,strlen(sendBuff),0);

int cc;
cc=recv(sockClient,recvBuf,1024*200,0);
char * tempBuf = recvBuf;
while(cc!=SOCKET_ERROR&&cc>0)
{
//循环下载网页数据并保存到map
while (boost::regex_search(tempBuf,httpSet,regStr))
{
string templink(httpSet[0].first,httpSet[0].second);//保存超链接
string tempserver(httpSet[1].first,httpSet[1].second);
char *const server = const_cast<char *>(tempserver.c_str());
web[server].push_back(const_cast<char *>(templink.c_str()));
tempBuf = const_cast<char *>(httpSet[0].second);
outFile<<tempserver<<endl;
outFile<<templink<<endl;
}
cc=recv(sockClient,recvBuf,1024*200,0);
}
}
家鸣 2008-04-21
  • 打赏
  • 举报
回复
回复楼主:
请问大康是做搜索的吗?
我不是做搜索的,但想往这方面发展。
我没有做笔记的习惯,所以也无法提供笔记给你。
为什么还要分析端口呢? http不一定就是固定在80端口,我认为分析端口并不会增加URL的处理难度。
最大跳转的深度是指层数吗?是的,怎么实现?以楼主的聪明才智应该可以解决这个问题。
如何判断是死链接,什么原理? Http的响应流都会有个对应的状态代码,如正常返回的是200。依据这个就可判断。
搜索引擎,建立索引采用什么样的数据库技术? 这个可以说是搜索引擎的核心技术,涉及有:分词,词频统计,词权重,反向索引,等。
由专门的数据库来处理,也就是可能需要设计一个这样的数据库。

词权重:就是对于某个页面,关键词可能出现在页面的不同位置,如出现在标题、关键词域,权重就高些,出现在正文权重可能就低些。词频高的,权重也高些。
另外一个好的搜索引擎,也可能会去考虑页面的重要性(级别),出现在重要页面上的关键词,权重也会变得高些。
至于页面的重要性,这个又是个技术活,也就是可能从互联网上链接到该网页的链接数来确定。
索引:对于某个页面,进行关键词检索。
反向索引:对于某个关键词,列出出现了这个关键词的页面。
至于关键词跟页面的相关性,这其实就是体现一个搜索引擎好坏的主要指标。原理:就是上面提及的词权重, 查询时按照词权重从高到低列出相关网页。

另外:楼主的求知欲非常强,不错。其实搜索引擎就是个很好的老师,利用好它可以满足你求知欲的。
不想低调 2008-04-21
  • 打赏
  • 举报
回复
up
aniuman 2008-04-21
  • 打赏
  • 举报
回复
mark
tianjiao85 2008-04-21
  • 打赏
  • 举报
回复
谢谢。
在大家的帮助下,最近学了不少,
研究这个很有趣,涉及太多方面,对能力的确锻炼不少,的确是个很好的老师。

例外看到有本搜索引擎原理,讲的主要是北大天网的设计,收益很多。
打算总结这些天的收获,看写个小代码来尝试下。

再次谢谢大家,特别是大康。
tianjiao85 2008-04-20
  • 打赏
  • 举报
回复
顶,不错,
也可以搞个BBS,
饭饭之辈 2008-04-20
  • 打赏
  • 举报
回复
学习,同时感到惭愧!!
tianjiao85 2008-04-20
  • 打赏
  • 举报
回复
大侠们,
做搜索引擎,建立索引时,采用什么样的数据库技术,最大化提高用户查询时的速度呢?
xiaoc10 2008-04-20
  • 打赏
  • 举报
回复
mark
tianjiao85 2008-04-20
  • 打赏
  • 举报
回复
有人知道这个吗?如何判断是死链接,什么原理?
写代码用什么函数?我用winsock。
tianjiao85 2008-04-20
  • 打赏
  • 举报
回复
larbin 有没有WINDOWS的版本
tianjiao85 2008-04-20
  • 打赏
  • 举报
回复
TO 1-34 楼:
谢谢各位的参与,使我收获很多,
学到不少,再等待高人,,up
coolzdp 2008-04-20
  • 打赏
  • 举报
回复
lz先自己写一写,看看会遇到什么问题,
然后可参考一下larbin的源码,c++的
tianjiao85 2008-04-20
  • 打赏
  • 举报
回复
楼上说得也是,不过目前偶还没水平,写不出出蜘蛛,现在想深入理解,等想出个好的解决方案后再试试吧。
[Quote=引用 31 楼 tianjiao85 的回复:]
增加URL可以最大跳转的深度,以控制它的收敛速度
最大跳转的深度是只层数吗?
我看说一般最深3层,
我听有人说做到了两层,
如果是层的话,这个层控制怎么实现呢,用个记号吗?呵呵,猜测,
我想会不会要用到是个什么数据结构吧,这个层怎么实现呢?大侠。
[/Quote]
m60a1 2008-04-20
  • 打赏
  • 举报
回复
其实LZ可以这样,找一台好点的机器(最好是高端服务器),运行爬虫程序。然后放着不要去管它,看一晚下来,抓取到多少有用信息,有没有得到你心里的结果。
爬虫程序的运行不是靠一台电脑来完成的LZ首先要明白,你电脑的假死状态并不代表服务器也接受不了,看看GOOGLE的服务器群,都在干什么!!:)
icosagon 2008-04-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 tianjiao85 的回复:]
请大侠给我找找错误,
现在领悟到了,写代码容易,找错难啊。
[/Quote]

晕,编译问题,找错真正难的不是这个
baihacker 2008-04-19
  • 打赏
  • 举报
回复

//VC6编译通过...你的正则式写错了,lib没有加,还有几个str函数的域错了,map<char *,vector<char *> > web;>>改成> >
//没有来得及调试其它的了,有事闪先
#include <WinSock2.h>
#include <cstring>
#include <vector>
#include <fstream>
#include <map>
#include <iostream>
#include <boost/regex.hpp>
using namespace std;

#pragma comment( lib , "ws2_32.lib")

map<char *,vector<char *> > web;

char recvBuf[1024*200+1] = {0}; //接收缓冲区
char sendBuff[200] = "GET "; //发送缓冲区
char *str = "http://(\\w+\\.\\w+\\.\\w+)(/\\w+)*(/\\w+\\.\\w){1}";
boost::basic_regex<char> regStr(str);//查找http的正则表达式
boost::cmatch httpSet; //保存匹配的http

bool connectServ(const char *);//连接服务器,并下载网页
void getPage(char *server,
char * http,
SOCKET &sockClient,
map<char *,vector<char *> > &web); // 下载网页

int main(int argc, char **argv)
{
ofstream outFile;
char * const index="www.hnu.cn";
web[index].push_back("http://www.hnu.cn/");
map<char *,vector<char *> >::iterator map_It = web.begin();
for (;map_It != web.end();map_It++)
{
//从map对象中读取服务器和网址进行访问
connectServ(map_It->first);
}

outFile.open("http.txt",ios::out|ios::app);
for (;map_It != web.end();map_It++)
{
outFile<<"Server: "<<map_It->first<<endl;
vector<char *>::iterator beg_it = map_It->second.begin();
vector<char *>::iterator end_it = map_It->second.end();
for (;beg_it != end_it; beg_it++)
{
//打印服务器下所有网址
outFile<<*beg_it<<endl;
}
}
return 0;
}

bool connectServ(char * const &server)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return false;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return false;
}

SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;



hostent* remoteHost;
char * const host_name= server;
unsigned int addr;
if (isalpha(host_name[0]))
{ /* host address is a name */
if (host_name[strlen(host_name)-1] == '\n')
host_name[strlen(host_name)-1] = '\0';
remoteHost = gethostbyname(host_name);
}
else
{
addr = inet_addr(host_name);
remoteHost = gethostbyaddr((char *)&addr, 4, AF_INET);
}

::memcpy(&addrSrv.sin_addr.S_un.S_addr,remoteHost->h_addr,remoteHost->h_length);
if (WSAGetLastError() != 0)
{
if (WSAGetLastError() == 11001)
printf("Host not found...\nExiting.\n");
}
else
printf("error#:%ld\n", WSAGetLastError());

addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(80);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
vector<char *>::iterator iter = web[server].begin();
for (;iter != web[server].end();iter++)
{
//下载一个服务器上的网页
getPage(server, *iter,sockClient,web);
}


closesocket(sockClient);
WSACleanup();
cout<<"getPage success!"<<endl;

}

void getPage(char *server,char * http,SOCKET &sockClient,map<char *,vector<char *> > &web)
{
//http消息格式
::strcpy(sendBuff,http);
::strcpy(sendBuff," HTTP/1.0\r\nHost:");
::strcpy(sendBuff,server);
::strcpy(sendBuff,"\r\n\r\n");
send(sockClient,sendBuff,strlen(sendBuff),0);

int cc;
cc=recv(sockClient,recvBuf,1024*200,0);
char * tempBuf = recvBuf;
while(cc!=SOCKET_ERROR&&cc>0)
{
//循环下载网页数据并保存到map
while (boost::regex_search(tempBuf,httpSet,regStr))
{
string temp(httpSet[0].first,httpSet[0].second);
web[server].push_back(const_cast<char *>(temp.c_str()));
tempBuf = const_cast<char *>(httpSet[0].second);
}
cc=recv(sockClient,recvBuf,1024*200,0);
}
}




加载更多回复(31)

64,656

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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