C++ 使用libcurl抓取NCBI BioProject多页数据
C++ 使用libcurl抓取NCBI BioProject多页数据
本文提供了一个C++代码示例,该示例演示了如何使用libcurl库从NCBI BioProject网站上抓取基因相关的多页数据。
问题描述
最初的代码只能抓取并输出NCBI BioProject搜索结果的第一页内容,而无法获取所有页面的内容。
解决方案
以下代码已修正了这个问题,能够抓取所有页面的内容并提取Accession号:
#include <iostream>
#include <fstream>
#include <string>
#include <curl/curl.h>
// 回调函数,用于处理libcurl接收到的数据
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) {
size_t total_size = size * nmemb;
output->append((char*)contents, total_size);
return total_size;
}
int main() {
// 输入基因名字
std::string gene_name;
std::cout << '请输入基因名字:';
std::cin >> gene_name;
// 构建搜索URL
std::string search_url = 'https://www.ncbi.nlm.nih.gov/bioproject/?term=' + gene_name;
// 初始化libcurl
curl_global_init(CURL_GLOBAL_ALL);
CURL* curl = curl_easy_init();
if (curl) {
// 设置libcurl选项
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
// 创建回调函数的输出字符串
std::string response;
// 声明当前页和总页数的变量
size_t current_page = 1;
size_t total_pages = 1;
// 循环执行HTTP请求直到获取所有页的结果
while (current_page <= total_pages) {
// 设置回调函数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
// 发送请求并检查是否成功
curl_easy_setopt(curl, CURLOPT_URL, (search_url + '&page=' + std::to_string(current_page)).c_str());
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
std::cerr << '请求失败:' << curl_easy_strerror(res) << std::endl;
return 1;
}
// 在response中查找总页数
if (current_page == 1) {
size_t page_start_pos = response.find('Page 1 of ');
if (page_start_pos != std::string::npos) {
size_t page_end_pos = response.find('</div>', page_start_pos);
std::string page_info = response.substr(page_start_pos, page_end_pos - page_start_pos);
total_pages = std::stoi(page_info.substr(10));
}
}
// 在response中查找Accession号
size_t start_pos = 0;
while ((start_pos = response.find('Accession:', start_pos)) != std::string::npos) {
size_t accession_start = start_pos + 10;
size_t accession_end = response.find('</dd>', accession_start);
std::string accession_number = response.substr(accession_start, accession_end - accession_start);
std::ofstream output_file('accession_numbers.txt', std::ios::app);
if (output_file.is_open()) {
output_file << accession_number << std::endl;
output_file.close();
} else {
std::cerr << '无法打开文件' << std::endl;
return 1;
}
start_pos = accession_end;
}
// 当前页数加1
current_page++;
// 重置response字符串
response = '';
}
// 关闭libcurl
curl_easy_cleanup(curl);
std::cout << 'Accession号已写入accession_numbers.txt' << std::endl;
} else {
std::cerr << '无法初始化libcurl' << std::endl;
return 1;
}
// 清理libcurl
curl_global_cleanup();
return 0;
}
代码解释
- 获取总页数: 代码首先获取搜索结果的总页数。在第一次请求后,解析HTML响应以找到包含总页数的信息,并将其存储在
total_pages变量中。 - 循环抓取: 使用
while循环迭代所有页面。在每次迭代中,代码都会构建一个新的URL,其中包含当前页码,并使用libcurl发送请求。 - 提取Accession号: 获取每个页面的HTML内容后,代码使用字符串查找函数 (
find) 定位并提取Accession号。 - 保存数据: 提取的Accession号会被写入到名为 'accession_numbers.txt' 的文件中。
总结
通过修改后的代码,您可以成功地从NCBI BioProject网站上抓取多页数据,并将所有Accession号保存到文件中。
原文地址: https://www.cveoy.top/t/topic/lanr 著作权归作者所有。请勿转载和采集!