读书人

初学者挤的代码弄了几天几夜现在都

发布时间: 2012-08-15 16:57:17 作者: rapoo

菜鸟挤的代码,弄了几天几夜,现在都不知道该怎么通过编译了,请大家帮帮忙。
使用的是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 *>>,既是服务器和它的网页。

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

C/C++ code
#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;        //保存匹配的httpbool 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);    }} 



[解决办法]
bool connectServ(const char *)
bool connectServ(char * const &server)
声明和定义必须一模一样,否则会链接错误。
[解决办法]
up
[解决办法]
这种问题 一个是:没有包含头文件
第二个是: 没有引入lib库

[解决办法]
引入Ws2_32.lib 试试
[解决办法]
map<char *,vector<char *>> web;

//=============
这句是因为csdn会过滤空格还是怎么着?
>>这个应该有空格吧.不然出错.

vc的工程设置里 ,link页-输入,包含库: ws2_32.lib
[解决办法]
C/C++ code
//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;        //保存匹配的httpbool 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);    }} 


[解决办法]

探讨
请大侠给我找找错误,
现在领悟到了,写代码容易,找错难啊。

[解决办法]
学习。 UP
[解决办法]
难的是稳定性、可靠性调试。。。。
[解决办法]
只是编译通过..什么都说明不了..也许灾难才刚开始:)
开个玩笑,小程序的话,自己对代码理解得透彻的话,仔细点是没有什么问题的
编程,基本功还是要扎实

我想代码的问题,飞雪辛苦都基本帮你解决了吧:)
[解决办法]
想做搜索引擎方面的工作?
[解决办法]
加ws2_32.lib
[解决办法]
MARK
[解决办法]
顶,关注..
[解决办法]
不懂,帮顶
[解决办法]
学习一下................
[解决办法]
爬虫思路正确,网络爬虫一般就是按广度优先,或深度优先来遍历网络,但由于网络的数据是非常大的,所以采用上术的算法时还要加上必要的控制。如增加URL可以最大跳转的深度,以控制它的收敛速度。
1. 提升效率首先当然考虑多线程。
修改建议,大体上可作如下分解:
对URL的处理:分析,得到主机,端口,等。
用于维护主机名的队列: 注意到同一站点的DNS请求只做一次, 多线程共享,应考虑线程并发性,封装成类.
用于维护URL的队列: 多线程共享,应考虑线程并发性,封装成类.
处理访问过的url: 这个数据量是非常大的,应将它们记录到磁盘, 封装成类.
处理HTML文档: 封装成类.
周期调度:载入过期的URL到URL队列,准备访问。 封装成类.
说明:
主机名的队列:把主机名独立出URL,主要考虑这样可以很方便地控制爬虫对各个网站的访问。控制同一站点的DNS请求只做一次,如有些网点更新速度快,就可以设置访问频率来控制缩减爬虫对这些网点的访问周期,等。
URL的队列:这个主要为每一个运行的爬虫提供URL进行访问,还有对新增加的URL进行处理,当URL超出一定的数量时也可以考虑写入磁盘,少于一定数量再从磁盘读出等。爬虫结束时,写入磁盘,重新启动时载入。
访问过的url: 组织记录各个网点的URL,通过主机名的频率控制,定期访问URL,等。
处理HTML文档: URL提取,内容处理:如对它进行索引(超出爬虫范围)等。

以上只是个人意见,功能划分不一定合适,按不同的需求,可作不同的划分,尽可能的模块化,功能独立.
[解决办法]
学习,同时感到惭愧!!
[解决办法]
其实LZ可以这样,找一台好点的机器(最好是高端服务器),运行爬虫程序。然后放着不要去管它,看一晚下来,抓取到多少有用信息,有没有得到你心里的结果。
爬虫程序的运行不是靠一台电脑来完成的LZ首先要明白,你电脑的假死状态并不代表服务器也接受不了,看看GOOGLE的服务器群,都在干什么!!:)
[解决办法]
lz先自己写一写,看看会遇到什么问题,
然后可参考一下larbin的源码,c++的
[解决办法]
mark
[解决办法]
mark
[解决办法]
up

读书人网 >C++

热点推荐