21xrx.com
2024-11-05 19:43:54 Tuesday
登录
文章检索 我的文章 写文章
使用C++爬取数据
2023-07-12 12:22:44 深夜i     --     --
C++ 爬虫 数据抓取 网络请求 数据处理

在当今互联网时代,大数据已经逐渐成为了各个领域发展的必要条件。而在获取大数据的过程中,网络爬虫技术更是必不可少。为了实现自动化采集数据的目标,很多开发者都在探索爬虫的最佳实践。其中,使用C++进行爬取数据就成为了极具技术含量的一种方法。

和其他语言相比,C++的优势在于它的高效性以及强大的内存管理能力。这意味着使用C++可以实现更加稳定、快速的网络爬虫程序,从而大大提升数据采集的效率和数据质量。

下面介绍一些C++爬取数据的基本方法:

1.网络请求

在C++中,使用Winsock库或者libcurl库可以实现网络请求。这两个库分别提供了对TCP/IP协议栈和HTTP协议的支持,使得爬虫能够非常方便地进行网络请求。使用这两个库的代码如下:

Winsock库:


#include <winsock2.h>

#include <iostream>

#pragma comment(lib, "ws2_32.lib")

int main()

{

  WSADATA wsaData;

  if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)

    std::cout << "WSAStartup failed" << std::endl;

    return -1;

  

  SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (sock == INVALID_SOCKET) {

    std::cout << "socket() failed" << std::endl;

    WSACleanup();

    return -1;

  }

  sockaddr_in addrServer;

  addrServer.sin_family = AF_INET;

  addrServer.sin_addr.s_addr = inet_addr("127.0.0.1");

  addrServer.sin_port = htons(80);

  if (connect(sock, (sockaddr*)&addrServer, sizeof(addrServer)) == SOCKET_ERROR) {

    std::cout << "connect() failed" << std::endl;

    closesocket(sock);

    WSACleanup();

    return -1;

  }

  std::string strRequest = "GET / HTTP/1.1\r\n";

  strRequest += "Host: www.baidu.com\r\n";

  strRequest += "Connection: close\r\n";

  strRequest += "\r\n";

  send(sock, strRequest.c_str(), strRequest.length(), 0);

  char buf[4096];

  int nRead;

  while ((nRead = recv(sock, buf, sizeof(buf), 0)) > 0) {

    std::cout.write(buf, nRead);

  }

  std::cout << std::endl;

  closesocket(sock);

  return 0;

}

libcurl库:


#include <curl/curl.h>

#include <iostream>

#include <string>

size_t callback(char* ptr, size_t size, size_t nmemb, std::string* str)

{

  str->append(ptr, size * nmemb);

  return size * nmemb;

}

int main()

{

  CURL* curl = curl_easy_init();

  if (curl) {

    std::string strUrl = "http://www.baidu.com";

    std::string strResult;

    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());

    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);

    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &strResult);

    CURLcode res = curl_easy_perform(curl);

    if (res != CURLE_OK) {

      std::cout << curl_easy_strerror(res) << std::endl;

    }

    std::cout << strResult << std::endl;

    curl_easy_cleanup(curl);

  }

  return 0;

}

其中,callback函数为回调函数,在数据接收完成后会被调用。代码中使用std::string来存储接收到的数据。

2.网页解析

C++提供了一些用于解析网页的库,例如libxml2和libhtmlcxx等。这些库可以帮助开发者有效地从网页中提取出目标数据。使用libhtmlcxx的代码如下:


#include <htmlcxx/html/ParserDom.h>

#include <iostream>

using namespace htmlcxx;

void PrintDom(const HTML::Node& node)

{

  if (node.isTag()) {

    std::cout << node.tagName() << std::endl;

  }

  for (auto it = node.begin(); it != node.end(); ++it) {

    PrintDom(*it);

  }

}

int main()

{

  std::string strHtml = "<html><body><div><p>hello world</p></div></body></html>";

  HTML::ParserDom parser;

  tree<HTML::Node> dom = parser.parseTree(strHtml);

  PrintDom(dom.root());

  return 0;

}

解析网页使用HTML::ParserDom库的parseTree函数,可以将网页的HTML代码转换成一个DOM树,方便之后的数据提取。

3.数据存储

在爬取数据完成后,数据需要进行存储。C++提供了多种数据存储方式,例如文件、数据库、缓存等。

文件存储:


#include <fstream>

int main()

{

  std::ofstream ofs("data.txt");

  if (!ofs.is_open()) {

    std::cout << "open file failed" << std::endl;

    return -1;

  }

  ofs << "hello world" << std::endl;

  ofs.close();

  return 0;

}

sql数据库存储:


#include <mysql/mysql.h>

#include <iostream>

int main()

{

  MYSQL mysql;

  mysql_init(&mysql);

  if (!mysql_real_connect(&mysql, "localhost", "admin", "password", "testdb", 0, NULL, 0)) {

    std::cout << mysql_error(&mysql) << std::endl;

    return -1;

  }

  std::string strSql = "insert into student(name, age) values ('test', 20)";

  if (mysql_real_query(&mysql, strSql.c_str(), strSql.length()) != 0) {

    std::cout << mysql_error(&mysql) << std::endl;

  }

  mysql_close(&mysql);

  return 0;

}

以MYSQL库为例,使用mysql_real_connect函数连接数据库,使用mysql_real_query函数执行SQL语句进行存储。

总结:

使用C++进行爬虫开发需要掌握TCP/IP、HTTP等相关协议,需要熟悉html、xml等网页解析方法,同时掌握各种数据存储方式。C++的高效性和内存管理能力使得爬虫程序更加稳定,大大提升了数据采集、解析、存储的效率,是一个非常值得探索的爬虫开发方法。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复