LinuxC/C++网络爬虫(1)

  网络爬虫(Web Crawler),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本,有时候又称网络蚂蚁,是搜索引擎(例如:BaiduGoogle……)的重要组成部分。随着Internet的快速发展,网站数量剧增意味着后台数据量的剧增,在这样的情况下,用户能不能通过搜索引擎来及时地得到包含他要查找内容的网页,能不能实现定向搜索……,这些对传统的搜索引擎必然是个巨大的考验。以上这些都是网络爬虫所关心的问题,通过改变网络爬虫的搜索策略,分析策略等,就能在很大程度上解决以上问题。

  传统的网络爬虫一般从一个或若干初始网页的URL开始,抓取初始网页,然后通过URL分析策略,提取已抓取页面上的URL,然后继续重复以上过程,不断从当前页面上抽取新的URL放入队列,直到满足一定的停止条件。

目前已经发布的网络爬虫有

RBSE Eichmann1994)是第一个发布的爬虫。

WebCrawlerPinkerton1994)是第一个公开可用的用来建立全文索引的一个子程序,他使用库www来下载页面。

World Wide Web Worm (McBryan, 1994)是一个用来为文件建立包括标题和URL简单索引的爬虫。索引可以通过grep式的Unix命令来搜索。

GNU Wget是一个在GPL许可下,使用C语言编写的命令行式的爬虫。它主要用于网络服务器和FTP服务器的镜像。

Heritrix是一个互联网档案馆级的爬虫,设计的目标为对大型网络的大部分内容的定期存档快照,是使用java编写的。

  大家常用的搜索引擎,例如BaiduGoogle也都有自己的网络爬虫来帮他们抓取Internet海洋中的网页。这里稍微插一段题外话,其实网络爬虫和网站维护经常都是对立的,因为有些爬虫刷新时间短,有些爬虫比较“笨”,会在网站里迷失了路等情况,引起给网站服务器发送大量请求,造成服务器压力过大而崩溃。但话又说回来,一个设计良好的网络爬虫,再加上使用者良好的素质,是完全可以避免以上情况的。总得来说,网络爬虫带来的好处远远大于它自身和使用者带来的坏处。


  因为刚开始接触这个网络爬虫的缘故,本人对爬虫了解并不是太深,这两天写了一个小程序,实现了通过URL来获取网页源代码。这两天找了很多资料,但是绝大部分的爬虫资料都是Python编写的,少数是JAVA和c#写的,C/C++的版本少之又少,还是需要我继续去学习啊。

#include 
#include 
#include 
#include 
#include 

using namespace std;

#define ERROR    -1
#define OK          0
#define PORT      80

void GetUrlAndPath(const string url, string &HostUrl, string &PagePath)
{
    HostUrl = url;
    PagePath = "/";
    //去除 http:// 字符串
    int pos = HostUrl.find("http://");
    if(pos != -1)
    {
        HostUrl = HostUrl.replace(pos, 7, "");
    }

    //去除 https:// 字符串
    pos = HostUrl.find("https://");
    if(pos != -1)
    {
        HostUrl = HostUrl.replace(pos, 8, "");
    }

    //提取主机端口和路径
    pos = HostUrl.find("/");
    if(pos != -1)
    {
        PagePath = HostUrl.substr(pos);
        HostUrl = HostUrl.substr(0, pos);
    }
}

string getpagecontent(const string url)
{
    //记录主机的信息,包括主机名、别名、地址类型、地址长度和地址列表
    struct hostent *host;
    string HostUrl, PagePath;

    //从url获取主机url和路径
    GetUrlAndPath(url, HostUrl, PagePath);

    //通过主机名连接主机
    host = gethostbyname(HostUrl.c_str());
    if(host == 0)
    {
        cout<<"gethostbyname error";
        exit(1);
    }

    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = ((struct in_addr*) (host->h_addr))->s_addr;
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd == -1)
    {
        cout<<"create sfd error"< 0)
    {
        buffer[len] = '\0';
        pagecontent += buffer;
    }

    return pagecontent;
}

int main()
{
    cout<


你可能感兴趣的:(linuxC语言学习)