记一次C语言编写的爬虫 wininet 堆糖爬虫

对 没错 嗯 用C语言写的爬虫

首先,既然是爬虫,当然要能够访问网页,用C访问网页的方法也有很多,这里选择的是一种相对比较方便的wininet,用InternetOpenUrl打开url然后读取数据就可以了

于是定义了一个获取网页源码的函数,ASSERT是个人习惯问题,见最后的完整代码

int GetUrl(char *url, char *buf, int *length){
    long unsigned int readDataLength;
    HINTERNET hinternet=InternetOpen(0,INTERNET_OPEN_TYPE_PRECONFIG,0,0,0);
    ASSERT(!hinternet,InternetCloseHandle(hinternet));
    HINTERNET hinternetopen=InternetOpenUrl(hinternet,url,0,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
    ASSERT(!hinternetopen,InternetCloseHandle(hinternet);InternetCloseHandle(hinternetopen));
    *length=0;
    do{
        InternetReadFile(hinternetopen,buf+*length,1024,&readDataLength);
        *length+=readDataLength;
    }while(readDataLength);
    return 1;
}

然后通过api获取数据之后的提取信息,如何分析api不是本文的内容不详细讨论,api接口如下:

#define API_URL "https://www.duitang.com/napi/blog/list/by_album/?album_id=%d&limit=24&start=%d"

提取信息就不要想着用regex了,C的正则库用过几个感觉都不怎么好用,甚至感觉不如自己写for循环,于是

void Parse(char *buf,int *now,int total,char *dest){
    char result[1024],name[1024];
    char *p,*q;
    for(p=buf;*p;p++){
        if(!strncmp(p,"path",4)){
            p+=12;
            strcpy(result,"http");
            for(q=result+4;*p!='"';p++,q++){
                *q=*p;
            }
            *q=0;
            //puts(result);
            GetFileName(result,name,dest);
            GetFile(result,name);
            printf("[%4d/%4d] %s\n",++*now,total,name);
        }
    }
}

思路就是找到每一项的path然后复制url,下面的获取文件数和获取文件名比较简单不多说了

int GetFileCount(char *buf,int *next){
    char *p;
    int total=0;
    if(p=strstr(buf,"total")){
        total=atoi(p+7);
        p=strstr(buf+7,"next_start");
        *next=atoi(p+12);
    }
    return total;
}

int GetFileName(char *name,char *buf,char *dest){
    char *last,*p,*q=buf;
    if(dest[1]==':'){
        p=dest;
        while(*q++=*p++);
        if(*(q-2)!='/'&&*(q-2)!='\\'){
            *(q-1)='/';
        }
    }
    for(p=name;*p;p++){
        if(*p=='/')
            last=p;
    }
    last++;
    while(*q++=*last++);
    //puts(buf);
    return 1;
}

然后是下载文件的问题,因为文件的大小是不知道的,可能大到内存放不下(你确定?<反正就是很大x>),本来想用wget的,后来一想,无依赖做到底算了,和获取网页类似,不过这里是每次1kb然后写到文件中

int GetFile(char *url, char *file){
    int length=0;
    char buf[1024];
    long unsigned int readDataLength;
    FILE *fp;
    HINTERNET hinternet=InternetOpen(0,INTERNET_OPEN_TYPE_PRECONFIG,0,0,0);
    ASSERT(!hinternet,InternetCloseHandle(hinternet));
    HINTERNET hinternetopen=InternetOpenUrl(hinternet,url,0,0,INTERNET_FLAG_NO_CACHE_WRITE,0);
    ASSERT(!hinternetopen,InternetCloseHandle(hinternet);InternetCloseHandle(hinternetopen));
    length=0;
    fp=fopen(file,"wb");
    ASSERT(!fp,InternetCloseHandle(hinternetopen);InternetCloseHandle(hinternet));
    do{
        InternetReadFile(hinternetopen,buf,1024,&readDataLength);
        fwrite(buf,1,readDataLength,fp);
        length+=readDataLength;
    }while(readDataLength);
    InternetCloseHandle(hinternetopen);
    InternetCloseHandle(hinternet);
    fclose(fp);
    return 1;
}

完整代码:Github

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MFC(Microsoft Foundation Class)是一个C++类库,用于在Windows操作系统上开发图形用户界面(GUI)应用程序。爬虫是一种程序,用于自动化地获取Web页面上的信息。在MFC中编写一个简单的爬虫,可以使用WinINet API来访问Web页面。 以下是一个简单的MFC爬虫程序,它使用WinINet API来获取Web页面的HTML代码,并在控制台窗口中显示: ```cpp #include <afxinet.h> #include <iostream> int main() { CInternetSession internetSession; CHttpFile* httpFile = nullptr; try { httpFile = (CHttpFile*)internetSession.OpenURL(_T("https://www.example.com")); } catch (CInternetException* e) { std::cout << "Failed to open URL: " << e->m_dwError << std::endl; e->Delete(); return 1; } CString htmlCode; CString line; while (httpFile->ReadString(line)) { htmlCode += line; } std::cout << "HTML code:\n" << htmlCode << std::endl; internetSession.Close(); httpFile->Close(); return 0; } ``` 在上面的例子中,我们使用了 `CInternetSession` 类来创建一个Internet会话对象。然后,我们使用 `OpenURL()` 方法打开一个URL,并将返回的 `CHttpFile` 对象转换为指向 `CHttpFile` 类的指针。接下来,我们使用 `ReadString()` 方法从 `CHttpFile` 对象中读取每一行HTML代码,并将其添加到 `htmlCode` 字符串中。最后,我们在控制台窗口中显示获取到的HTML代码,并关闭Internet会话和 `CHttpFile` 对象。 需要注意的是,这只是一个简单的示例程序,不能处理所有的Web页面。对于更复杂的爬虫功能,您可能需要使用其他开源C++库,例如libcurl或Boost.Beast。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值