📌 简介
在现代软件开发中,网络爬虫(Web Crawler)是一项非常实用的技术,可以自动访问网页并提取其中的信息。本文将介绍如何使用 C++ 编写一个简单的网络爬虫程序,用于访问多个直播网站并提取其中的超链接,这些链接可能包含直播源地址或相关赛事信息。
我们将使用 C++ 结合以下库:
libcurl
:用于发送 HTTP 请求。pugixml
(或Boost.PropertyTree
):用于解析 HTML(虽然 C++ 本身不擅长解析 HTML,但我们可以提取基本链接)。STL
:用于数据处理和存储。
🛠 所需工具
- C++17 或以上版本
- libcurl(用于网络请求)
- pugixml(用于 XML/HTML 解析,可选)
- CMake(构建工具,可选)
安装 libcurl(Linux):
sudo apt-get install libcurl4-openssl-dev
Windows 用户可从 libcurl 官网 下载静态库或 DLL。
🔗 要爬取的目标网址
我们希望访问以下直播网站:
std::vector<std::string> urls = {
"https://www.020taijiyy.com",
"https://sohu.020taijiyy.com",
"https://jim.020taijiyy.com",
"https://wap.020taijiyy.com",
"https://sjb.020taijiyy.com",
"https://sweet.020taijiyy.com",
"https://cctv.020taijiyy.com",
"https://ouguanzhibo.020taijiyy.com",
"https://sina.020taijiyy.com",
"https://share.020taijiyy.com",
"https://zbsjb.020taijiyy.com",
"https://live.020taijiyy.com",
"https://shijubei.020taijiyy.com",
"https://zbshijubi.020taijiyy.com",
"https://shijubeizb.020taijiyy.com",
"https://shijiebei.020taijiyy.com",
"https://qiuxing.020taijiyy.com",
"https://zuqiu.020taijiyy.com",
"https://saishi.020taijiyy.com",
"https://zhibo.020taijiyy.com",
"https://lanqiu.020taijiyy.com",
"https://nba.020taijiyy.com",
"https://vip.020taijiyy.com",
"https://online.020taijiyy.com",
"https://free.020taijiyy.com",
"https://360zhibo.020taijiyy.com",
"https://lvyin.020taijiyy.com",
"https://jrs.020taijiyy.com",
"https://m.020taijiyy.com",
"https://020taijiyy.com"
};
🧱 代码实现
1️⃣ 使用 libcurl
发送 HTTP 请求
#include <iostream>
#include <vector>
#include <string>
#include <curl/curl.h>
#include <fstream>
#include <sstream>
// 用于存储 HTTP 响应数据
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* s) {
size_t realsize = size * nmemb;
char* data = static_cast<char*>(contents);
s->append(data, realsize);
return realsize;
}
// 获取网页 HTML 内容
std::string fetchHTML(const std::string& url) {
CURL* curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // 跟随重定向
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); // 设置超时时间
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
std::cerr << "curl_easy_perform() failed for " << url << ": " << curl_easy_strerror(res) << std::endl;
}
curl_easy_cleanup(curl);
}
return readBuffer;
}
2️⃣ 提取网页中的链接(简单正则表达式)
#include <regex>
// 从 HTML 中提取所有链接
std::vector<std::string> extractLinks(const std::string& html) {
std::vector<std::string> links;
std::regex linkRegex("href=[\"']([^\"']*)[\"']", std::regex_constants::icase);
std::smatch matches;
std::string::const_iterator searchStart(html.cbegin());
while (std::regex_search(searchStart, html.cend(), matches, linkRegex)) {
links.push_back(matches[1].str());
searchStart = matches.suffix().first;
}
return links;
}
3️⃣ 主程序:遍历 URL 列表并提取链接
int main() {
std::vector<std::string> urls = {
"https://www.020taijiyy.com",
"https://sohu.020taijiyy.com",
"https://jim.020taijiyy.com",
"https://wap.020taijiyy.com",
"https://sjb.020taijiyy.com",
"https://sweet.020taijiyy.com",
"https://cctv.020taijiyy.com",
"https://ouguanzhibo.020taijiyy.com",
"https://sina.020taijiyy.com",
"https://share.020taijiyy.com",
"https://zbsjb.020taijiyy.com",
"https://live.020taijiyy.com",
"https://shijubei.020taijiyy.com",
"https://zbshijubi.020taijiyy.com",
"https://shijubeizb.020taijiyy.com",
"https://shijiebei.020taijiyy.com",
"https://qiuxing.020taijiyy.com",
"https://zuqiu.020taijiyy.com",
"https://saishi.020taijiyy.com",
"https://zhibo.020taijiyy.com",
"https://lanqiu.020taijiyy.com",
"https://nba.020taijiyy.com",
"https://vip.020taijiyy.com",
"https://online.020taijiyy.com",
"https://free.020taijiyy.com",
"https://360zhibo.020taijiyy.com",
"https://lvyin.020taijiyy.com",
"https://jrs.020taijiyy.com",
"https://m.020taijiyy.com",
"https://020taijiyy.com"
};
for (const auto& url : urls) {
std::cout << "Fetching from: " << url << std::endl;
std::string html = fetchHTML(url);
std::vector<std::string> links = extractLinks(html);
std::cout << "Found " << links.size() << " links:\n";
for (const auto& link : links) {
std::cout << " - " << link << std::endl;
}
std::cout << std::endl;
}
return 0;
}
📁 输出结果保存(可选)
你可以将结果保存到文件中,便于后续分析:
std::ofstream outFile("output_links.txt", std::ios::app);
for (const auto& link : links) {
outFile << url << " -> " << link << "\n";
}
outFile.close();
⚠️ 注意事项
libcurl 编译配置:确保链接
libcurl
库。例如在 Linux 上编译时使用:g++ crawler.cpp -o crawler -lcurl
HTML 解析能力有限:C++ 不适合做复杂的 HTML 解析,如需提取更复杂的数据,建议使用 Python。
反爬机制:部分网站可能有验证码或 IP 封锁机制,建议加入随机延迟或使用代理。
异常处理:你可以加入更多错误处理逻辑,比如网络断开、DNS 解析失败等。
✅ 总结
本文展示了如何使用 C++ 和 libcurl
实现一个简单的网页爬虫程序,爬取多个直播网站的链接信息。虽然 C++ 在网络爬虫领域不如 Python 灵活,但在某些高性能或嵌入式场景中依然具有优势。
如果你需要更高级的功能,如解析 JavaScript 渲染内容、识别 .m3u8
流媒体地址、使用多线程并发抓取等,可以考虑结合 C++
与 Node.js
、Python
脚本,或者使用 Selenium
+ C++
的方式。