最近有个公司找我,说他们在某图库充值会员,想要使用里面的图片,而是是海量,问我有没有办法做个筛选并下载保存,成了给我包个大红包。这事有啥难得,以我现在的专业知识储备,这种事情分分钟就解决。
以下是一个简单的C爬虫程序。在这个例子中,我们使用了libcurl库来发送HTTP请求和处理响应。我们还使用了pcre库来解析HTML并提取图片链接。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <pcre.h>#define URL "meitu"
#define PROXY_HOST "duoip"
#define PROXY_PORT "8000"
#define MAX_LINKS 10int main() {CURL *curl;CURLcode res;char *url, *proxy_host, *proxy_port;int i, n_links;char **links;pcre *re;pcre_extra *extra;// 初始化libcurl和libpcrecurl_global_init(CURL_GLOBAL_DEFAULT);re = pcre_compile("http://www\\.meitu\\.com/.*\\.jpg", PCRE_CASELESS | PCRE_EXTENDED, &extra, 0, NULL);if (re == NULL) {fprintf(stderr, "pcre_compile error: %s\n", extra->error_message);pcre_free_study(extra);curl_global_cleanup();return 1;}pcre_free_study(extra);// 创建一个CURL会话curl = curl_easy_init();if (curl) {// 设置代理服务器// 提取ip "jshk.com.cn/mb/reg.asp?kefu=xjy&csdn"proxy_host = (char *)malloc(strlen(PROXY_HOST) + 1);proxy_port = (char *)malloc(strlen(PROXY_PORT) + 1);strcpy(proxy_host, PROXY_HOST);strcpy(proxy_port, PROXY_PORT);curl_easy_setopt(curl, CURLOPT_PROXY, proxy_host);curl_easy_setopt(curl, CURLOPT_PROXY_PORT, proxy_port);// 设置URLurl = (char *)malloc(strlen(URL) + 1);strcpy(url, URL);// 发送HTTP请求curl_easy_setopt(curl, CURLOPT_URL, url);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);// 执行请求res = curl_easy_perform(curl);// 检查错误if (res != CURLE_OK) {fprintf(stderr, "curl_easy_perform error: %s\n", curl_easy_strerror(res));curl_easy_cleanup(curl);return 1;}// 释放资源curl_easy_cleanup(curl);// 解析HTML并提取图片链接n_links = parse_html(url, re, MAX_LINKS, &links);if (n_links < 0) {fprintf(stderr, "pcre_exec error: %s\n", re->error_message);pcre_free(re);return 1;}pcre_free(re);// 打印图片链接for (i = 0; i < n_links; i++) {printf("%s\n", links[i]);}free(links);}// 释放资源curl_global_cleanup();return 0;
}// 用于处理HTTP响应的回调函数
size_t write_callback(char *buffer, size_t size, size_t nmemb, void *userp) {size_t total = size * nmemb;FILE *fp = (FILE *)userp;if (fp) {fwrite(buffer, total, 1, fp);}return total;
}// 用于解析HTML并提取图片链接的函数
int parse_html(char *url, pcre *re, int max_links, char **links) {FILE *fp;char buffer[4096];int i, n_links;pcre_exec_t *match;// 打开URLfp = fopen(url, "r");if (fp == NULL) {fprintf(stderr, "fopen error: %s\n", strerror(errno));return -1;}// 逐行读取HTMLn_links = 0;while (fgets(buffer, sizeof(buffer), fp)) {// 使用正则表达式匹配图片链接match = pcre_exec(re, NULL, buffer, strlen(buffer), 0, 0, NULL, 0);if (match) {if (n_links >= max_links) {break;}links[n_links++] = malloc(strlen(buffer) + 1);strcpy(links[n_links - 1], buffer + match[1].offset);}}// 关闭文件fclose(fp);// 清理资源pcre_free_study(re);for (i = 0; i < n_links; i++) {free(links[i]);}return n_links;
}
这段代码首先初始化了libcurl和libpcre,然后创建了一个CURL会话并设置了代理服务器。然后,它发送了一个HTTP请求到指定的URL,并将响应写入到一个文件中。然后,它解析了HTML并提取了其中的所有图片链接。最后,它打印了这些链接并释放了资源。
注意,这个程序并没有处理任何错误,例如网络错误或文件I/O错误。在实际使用中,你可能需要添加错误处理代码。
虽然说我思路很清晰,但是写作过程中还是会出现一些小错误,这就要求我们在写作过程中一定要细心,否则出现一个小bug可能要花你大半时间来找问题。如果有相关问题可以评论区留言讨论。