2025 年使用 C 语言进行网络抓取
在这本简单的指南中,我将向你展示如何使用 C 语言创建网络刮擦工具。 XPath并将所有内容保存到 CSV 文件中。一开始听起来可能很棘手,但只要有正确的工具和步骤,即使是在 2025 年,也是可以做到的。让我们深入了解一下!
为什么在 2025 年使用 C 语言进行网络抓取?
尽管已有五十多年的历史,但 C 语言仍然是性能上的巨无霸。使用 C 语言进行网络抓取似乎不合常规,但其优势显而易见:
- 快速执行:非常适合搜索大流量或重内容网站。
- 精确的资源控制:尽量减少内存和 CPU 占用。
- 底层调试和优化:轻松发现瓶颈。
- 更好地整合:C 语言可用于嵌入式系统、微控制器或高性能集群。
考虑其他方法?
虽然 C 可以为您提供最大限度的控制和性能,但它可能需要大量的设置和维护,尤其是随着网络技术的发展。如果您需要从动态、受保护或快速变化的网站中提取数据,Bright Data 等现代刮擦平台可以简化这一过程。
Bright Data 和其他供应商提供的解决方案,如托管代理网络、浏览器自动化和 预建应用程序接口.这些方法有助于自动执行刮擦任务、处理复杂网站并节省开发时间。根据您的使用情况,在使用基于 C 语言的方法的同时,也值得探索这些选项。
循序渐进:用 C 语言构建网络抓取器
你需要的工具
使用软件包管理器(如 vcpkg 或系统的软件包管理器:
vcpkg install curl libxml2
或者用于 Ubuntu/Debian 系统:
sudo apt-get install libcurl4-openssl-dev libxml2-dev
您需要
- libcurl - 用于进行 HTTP 请求
- libxml2 - 使用 XPath 解析 HTML
步骤 1:安装依赖项
在开始编写代码之前,请先设置好环境。
关于 Linux/macOS:
sudo apt install libcurl4-openssl-dev libxml2-dev
关于 视窗 使用 vcpkg:
vcpkg install curl libxml2
确保您的开发环境已配置为与这些库链接。
步骤 2:设置基本 C 爬虫
创建一个名为 scraper.c 的文件。从基本的包含项和一个 "Hello World "开始,以验证您的设置:
#包括
#包括
#包括 <curl/curl.h>
#包括 <libxml/HTMLparser.h>
#包括 <libxml/xpath.h>
int main() {
printf("用 C 语言进行网络抓取 - 2025!n");
return 0;
}
编译时使用
gcc scraper.c -o scraper -lcurl -lxml2
如果一切正常,就可以开始了。
步骤 3:使用 libcurl 抓取网页
接下来,编写一个函数来执行 HTTP GET 请求 并捕捉 HTML:
结构 CURLResponse {
烧掉 *html;
size_t size;
};
static size_t WriteHTMLCallback(void *内容、 size_t 尺寸 size_t nmemb、 void *userp) {
size_t realsize = size * nmemb;
结构 CURLResponse *mem = (结构 CURLResponse *)userp;
烧掉 *ptr = 重新分配(mem->html,mem->size realsize 1);
if (!ptr) return 0;
mem->html = ptr;
memcpy(&(mem->html[mem->size]), contents, realsize);
mem->size = realsize;
mem->html[mem->size] = 0;
return realsize;
}
结构 CURLResponse 获取 HTML(const 烧掉 *url) {
CURL *curl = curl_easy_init();
结构 CURLResponse res = {.html = 调用(1), .size = 0};
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,WriteHTMLCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&res);
curl_easy_setopt(curl, CURLOPT_USERAGENT、 "Mozilla/5.0");
curl_easy_perform(卷曲);
curl_easy_cleanup(卷曲);
return res;
}
现在,您可以调用 GetHTML("https://example.com") 来获取原始 HTML。
步骤 4:使用 libxml2 解析 HTML
让我们使用 XPath 查询从获取的 HTML 中提取有意义的内容。
htmlDocPtr ParseHTML(const 烧掉 *html、 size_t 尺寸) {
return htmlReadMemory(html,大小、 NULL, NULL} } html_parse_noerror | html_parse_nowarning);
}
xmlXPathObjectPtr GetNodesByXPath(htmlDocPtr doc、 const 烧掉 *xpathExpr) {
xmlXPathContextPtr context = xmlXPathNewContext(文件);
return xmlXPathEvalExpression((xmlChar *)xpathExpr, context);
}
步骤 5:定义数据结构
使用结构体存储产品数据:
类型化 结构 {
烧掉 *url;
烧掉 *image;
烧掉 *name;
烧掉 *价格;
}产品;
#定义 max_products 192
步骤 6:搜索产品数据
假设您正在抓取一个带有结构化 HTML 的电子商务演示网站。下面是提取产品信息的方法:
int 提取物产品(htmlDocPtr doc, Product *products、 int startIndex) {
xmlXPathContextPtr context = xmlXPathNewContext(文档);
xmlXPathObjectPtr items = xmlXPathEvalExpression((xmlChar *)"//li[包含(@class,'产品')]"上下文);
int 计数 = 0;
for (int i = 0i nodesetval->nodeNr; i) {
xmlNodePtr node = items->nodesetval->nodeTab[i];
xmlXPathSetContextNode(节点,上下文);
烧掉 *url = (烧掉 *)xmlGetProp(xmlXPathEvalExpression((xmlChar *)".//a", 上下文)->节点集值->节点标签[...0], (xmlChar *)"href");
烧掉 *img = (烧掉 *)xmlGetProp(xmlXPathEvalExpression((xmlChar *)".//a/img", 上下文)->节点集值->节点标签[...0], (xmlChar *)"src");
烧掉 *name = (烧掉 *)xmlNodeGetContent(xmlXPathEvalExpression((xmlChar *)".//a/h2", 上下文)->节点集值->节点标签[...0]);
烧掉 *价格 = (烧掉 *)xmlNodeGetContent(xmlXPathEvalExpression((xmlChar *)".//a/span", 上下文)->节点集值->节点标签[...0]);
products[startIndex count].url = 查询(url);
产品[startIndex count].image = 查询(img);
产品[startIndex count].name = 查询(名称);
products[startIndex count].price = 查询(价格);
计数 ;
免费的(url); 免费的(img); 免费的(名字); 免费的(价格);
}
xmlXPathFreeContext(上下文);
xmlXPathFreeObject(项);
return count;
}
第 7 步:将数据导出为 CSV
获取数据后,将其导出:
void ExportToCSV(产品 *products、 int 计数) {
FILE *fp = fopen("products.csv", "w");
fprintf(页码、 "URL、图像、名称、价格");
for (int i = 0; i < count; i ){
fprintf(页码、 ""%s","%s","%s","%s"n",
产品[i].url、产品[i].图片、产品[i].名称、产品[i].价格);
}
fclose(fp);
}
步骤 8:抓取多个页面
许多网站对产品进行分页。例如
https://example.com/products/page/1/
https://example.com/products/page/2/
循环浏览这些页面:
#定义 总页数 5
int main() {
curl_global_init(curl_global_all);
产品 products[MAX_PRODUCTS];
int 总数 = 0;
for (int page = 1; page <= TOTAL_PAGES; page) {
烧掉 url[256];
snprintf(url、 尺寸(url)、 "https://example.com/products/page/%d/"页);
结构 CURLResponse 恢复 = 获取 HTML(url);
htmlDocPtr doc = ParseHTML(res.html, res.size);
int 计数 = 提取物产品(文档、产品、总数);
totalCount = count;
xmlFreeDoc(文件);
免费的(res.html);
}
ExportToCSV(产品,总数);
for (int i = 0; i < TotalCount; i ){
免费的(产品[i].url);
免费的(产品[i].图像);
免费的(产品[i].名称);
免费的(products[i].price);
}
curl_global_cleanup();
return 0;
}
2025 年的反偷窃措施
2025 年的网站更加智能。您必须注意
- 费率限制:增加请求之间的延迟。或者,查看我的 最佳旋转代理.
- 页眉:使用符合实际的 User-Agent、Accept 和 Referer 值。
- 会话 cookie:必要时,在所有请求中保留 cookie。
- 验证码:在没有浏览器自动化的情况下,用 C 语言绕过这些问题比较困难。查看我的文章,了解最好的 验证码解决工具.
下面介绍如何使用标头模拟真实浏览器:
curl_easy_setopt(curl,CURLOPT_HTTPHEADER,curl_slist_append(NULL, "Accept: text/html"));
用 C 语言进行网络抓取的未来
虽然由于缺乏无头浏览器引擎,C 语言无法本地支持使用 JavaScript 的动态网站,但有两种方法可以解决这个问题:
- 使用中间渲染服务 (HTML 快照提供商)。
- 卸载 JavaScript 渲染 其他服务,只用 C 语言处理原始 HTML。
有一些新兴项目正在探索使用 C 或 C 语言进行轻量级无头渲染,但 C 语言最好用于需要原始性能的静态或半静态网站。
结论
在 2025 年使用 C 语言进行网络刮擦是一种引人注目的先进做法。它具有无与伦比的速度和控制能力,非常适合内存的每一个字节和每一毫秒都至关重要的专业应用。通过利用 libcurl 和 libxml2 等功能强大的库,并遵守负责任的刮擦原则,您可以用 C 语言构建强大而高效的刮擦解决方案。
无论您是在刮擦电子商务页面、收集研究数据,还是在受限环境中嵌入刮擦逻辑,C 语言仍然是您开发人员工具包中的高性能工具。