最近有个公司找我,说他们在某图库充值会员,想要使用里面的图片,而是是海量,问我有没有办法做个筛选并下载保存,成了给我包个大红包。这事有啥难得,以我现在的专业知识储备,这种事情分分钟就解决。
以下是一个简单的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 10
int main() {
CURL *curl;
CURLcode res;
char *url, *proxy_host, *proxy_port;
int i, n_links;
char **links;
pcre *re;
pcre_extra *extra;
// 初始化libcurl和libpcre
curl_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);
// 设置URL
url = (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;
// 打开URL
fp = fopen(url, "r");
if (fp == NULL) {
fprintf(stderr, "fopen error: %s\n", strerror(errno));
return -1;
}
// 逐行读取HTML
n_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可能要花你大半时间来找问题。如果有相关问题可以评论区留言讨论。