用C语言写爬虫并不是稀奇事,核心思路就是利用操作系统提供的网络接口,自己构造HTTP请求发给服务器,再把返回的数据收下来做文本处理。这种方式没有高级语言的封装,但换来的是对每一个字节的掌控力。

一、C语言爬虫的基本原理
网络爬虫的本质是客户端按照HTTP协议规范,向服务端发起请求并接收响应。在C语言里,我们通常使用BSD socket(在Linux下是sys/socket.h,Windows下是winsock2.h)来建立TCP连接,连接目标的80端口(HTTP)或443端口(HTTPS,需额外处理TLS)。由于HTTPS涉及加密,初学者建议先从明文HTTP入手。
建立连接后,需要按照HTTP/1.1格式发送请求行和请求头,例如“GET /index.html HTTP/1.1”加上“Host: ipipp.com”等字段。服务器响应后,先返回状态行、响应头,空一行之后才是正文。C语言没有内置的字符串高级函数,我们需要用recv()循环读取,把数据追加到缓冲区,再根据Content-Length或者连接关闭来判断是否接收完毕。
二、一个简单的HTTP抓取示例
下面这段代码演示了如何用C语言通过socket获取一个网页的HTML源码。代码中使用了标准POSIX接口,在Linux环境可直接编译运行。我们以ipipp.com为例,实际使用时请确认对方允许抓取。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main() {
// 创建TCP socket
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket fail");
return 1;
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(80);
// 设置目标IP,这里用示例域名对应的地址
inet_pton(AF_INET, "93.184.216.34", &server.sin_addr);
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
perror("connect fail");
close(sock);
return 1;
}
// 构造HTTP请求
const char *req = "GET / HTTP/1.1rnHost: ipipp.comrnConnection: closernrn";
send(sock, req, strlen(req), 0);
// 循环接收响应
char buf[1024];
int len;
while ((len = recv(sock, buf, sizeof(buf) - 1, 0)) > 0) {
buf[len] = ' ';
printf("%s", buf);
}
close(sock);
return 0;
}
上面的代码通过Connection: close告知服务器完成一次请求后关闭连接,这样recv返回0时就代表数据接收完了。如果你抓取的页面使用了分块传输编码(Transfer-Encoding: chunked),还需要在应用层解析每个chunk的长度,这属于进阶处理。
编译命令一般是gcc crawler.c -o crawler,运行后终端会打印出网页的原始HTML。你可以把printf部分改为写入文件,或者用strstr函数去查找<title>标签提取标题,这就成了一个微型爬虫。
三、解析内容与注意事项
拿到HTML文本后,C语言里通常用字符串函数如strstr、strtok来做简单提取。例如要找网页标题,可以搜索“<title>”和“</title>”之间的内容。但要注意HTML可能有大小写混用、属性干扰,严谨做法是用正则库如POSIX regex或者第三方解析库。
写C爬虫时必须注意两点:一是不要高频访问同一站点,应在每次请求之间用sleep控制节奏;二是遵守目标站点的robots.txt规则。另外,如果目标使用HTTPS,原生socket无法直接解密,需要引入OpenSSL等库,代码复杂度会明显上升。对于大规模抓取,C语言在内存管理和并发上需要格外小心,避免内存泄漏和句柄耗尽。
四、总结
用C语言做爬虫适合理解网络协议底层、或者对性能与资源占用有严苛要求的场景。它的优势是依赖少、可控性强,劣势是开发效率低于Python等语言。掌握socket收发与HTTP格式之后,你就能根据需求逐步加上URL队列、多线程和解析模块,搭建出属于自己的C语言爬虫工具。