C++下载器程序:如何使用cpprestsdk库下载www.ebay.com图片

news2024/11/20 7:06:05

亿牛云代理.png

本文介绍了如何使用C++语言和cpprestsdk库编写一个下载器程序,该程序可以从www.ebay.com网站上下载图片,并保存到本地文件夹中。为了避免被网站屏蔽,我们使用了亿牛云爬虫代理服务提供的代理IP地址,以及多线程技术提高下载效率。

  1. 首先,我们需要安装cpprestsdk库,这是一个跨平台的C++库,提供了一些方便的网络编程功能。我们可以使用vcpkg工具来安装它,具体步骤如下:
    • 下载并安装vcpkg工具。
    • 在命令行中运行vcpkg install cpprestsdk命令,等待安装完成。
    • 在项目中添加cpprestsdk库的引用。
  2. 其次,我们需要注册亿牛云爬虫代理服务,并获取域名、端口、用户名和密码。这是一个提供高质量代理IP地址的服务,可以帮助我们隐藏真实的IP地址,防止被网站识别和封锁。我们可以在www.16yun.cn注册并查看相关信息。
  3. 然后,我们需要编写一个下载器类,用来封装下载图片的功能。该类的主要成员如下:
    • 一个http_client对象,用来发送HTTP请求和接收HTTP响应。
    • 一个vector<string>对象,用来存储要下载的图片的URL地址。
    • 一个string对象,用来存储要保存图片的本地文件夹路径。
    • 一个mutex对象,用来保证多线程操作的线程安全性。
    • 一个构造函数,用来初始化上述成员,并设置代理服务器的信息。
    • 一个download_image函数,用来根据给定的图片URL地址下载图片,并保存到本地文件夹中。
    • 一个download_all_images函数,用来启动多个线程,并调用download_image函数下载所有图片。
  4. 最后,我们需要编写主函数,用来创建下载器对象,并调用其download_all_images函数。我们还需要在代码中添加一些异常处理和日志输出的代码,以便于调试和监控程序的运行情况。

代码如下:

// 引入必要的头文件
#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <mutex>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>

using namespace std;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace concurrency::streams;

// 定义下载器类
class Downloader {
private:
    // http_client对象
    http_client client;
    // 图片URL地址列表
    vector<string> image_urls;
    // 本地文件夹路径
    string folder_path;
    // mutex对象
    mutex mtx;

public:
    // 构造函数,初始化成员,并设置代理服务器的信息
    Downloader(const string& url, const vector<string>& urls, const string& folder) : client(url), image_urls(urls), folder_path(folder) {
        // 置代理服务器的域名、端口、用户名和密码,这里使用亿牛云爬虫代理加强版服务提供的信息,你可以根据自己的需要修改
        web_proxy proxy(U("www.16yun.cn:9020"));
        proxy.set_credentials(web::credentials(U("16YUN"), U("16IP")));
        client_config config;
        config.set_proxy(proxy);
        client = http_client(url, config);
    }

    // 下载图片函数,根据给定的图片URL地址下载图片,并保存到本地文件夹中
    void download_image(const string& image_url) {
        try {
            // 发送GET请求,获取图片的HTTP响应
            http_response response = client.request(methods::GET, image_url).get();
            // 检查HTTP响应的状态码,如果是200,表示成功
            if (response.status_code() == status_codes::OK) {
                // 获取图片的内容类型,例如image/jpeg
                string content_type = response.headers().content_type();
                // 获取图片的后缀名,例如.jpg
                string extension = content_type.substr(content_type.find('/') + 1);
                // 获取图片的文件名,例如123.jpg
                string file_name = image_url.substr(image_url.find_last_of('/') + 1) + "." + extension;
                // 获取图片的本地文件路径,例如C:/images/123.jpg
                string file_path = folder_path + "/" + file_name;
                // 创建一个本地文件流对象,用来写入图片数据
                auto file_stream = fstream::open_ostream(file_path).get();
                // 将HTTP响应的内容写入本地文件流中
                response.body().read_to_end(file_stream.streambuf()).get();
                // 关闭本地文件流对象
                file_stream.close().get();
                // 上锁,防止多线程输出冲突
                mtx.lock();
                // 输出日志信息,表示下载成功
                cout << "Downloaded " << image_url << " to " << file_path << endl;
                // 解锁
                mtx.unlock();
            }
            else {
                // 如果HTTP响应的状态码不是200,表示失败,输出错误信息
                throw http_exception(response.status_code());
            }
        }
        catch (const exception& e) {
            // 捕获并处理异常,输出异常信息
            mtx.lock();
            cerr << "Error downloading " << image_url << ": " << e.what() << endl;
            mtx.unlock();
        }
    }

    // 下载所有图片函数,启动多个线程,并调用download_image函数下载所有图片
    void download_all_images() {
        try {
            // 创建一个线程列表
            vector<thread> threads;
            // 遍历图片URL地址列表,为每个URL地址创建一个线程,并调用download_image函数
            for (const string& image_url : image_urls) {
                threads.push_back(thread(&Downloader::download_image, this, image_url));
            }
            // 等待所有线程结束
            for (thread& t : threads) {
                t.join();
            }
            // 输出日志信息,表示下载完成
            cout << "Downloaded all images." << endl;
        }
        catch (const exception& e) {
            // 捕获并处理异常,输出异常信息
            cerr << "Error downloading all images: " << e.what() << endl;
        }
    }
};

// 主函数,创建下载器对象,并调用其download_all_images函数
int main() {
    try {
        // 定义要下载的网站的URL地址,这里使用www.ebay.com网站作为示例,你可以根据自己的需要修改
        string website_url = "http://www.ebay.com";
        // 定义要下载的图片的URL地址列表,这里只列出了部分URL地址作为示例,你可以根据自己的需要修改或添加更多的URL地址
        vector<string> image_urls = {"/img/ebay_logo.png", "/img/hero_il
        // 定义要下载的图片的URL地址列表,这里只列出了部分URL地址作为示例,你可以根据自己的需要修改或添加更多的URL地址
        vector<string> image_urls = {"/img/ebay_logo.png", "/img/hero_il_570xN.3130538910_8w2u.jpg", "/img/il_570xN.3130538910_8w2u.jpg", "/img/il_570xN.3130538910_8w2u.jpg"};
        // 定义要保存图片的本地文件夹路径,这里使用C:/images文件夹作为示例,你可以根据自己的需要修改
        string folder_path = "C:/images";
        // 创建下载器对象,传入网站URL地址,图片URL地址列表和本地文件夹路径
        Downloader downloader(website_url, image_urls, folder_path);
        // 调用下载器对象的download_all_images函数,开始下载所有图片
        downloader.download_all_images();
        }
    }

本文介绍了如何使用C++语言和cpprestsdk库编写一个下载器程序,该程序可以从www.ebay.com网站上下载图片,并保存到本地文件夹中。我们使用了亿牛云爬虫代理服务提供的代理IP地址,以及多线程技术提高下载效率。这是一个简单而实用的示例,可以作为学习爬虫技术的入门教程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1088629.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

02 | Spring Data Common 之 Repository 如何全面掌握?

通过上一课时&#xff0c;我们知道了 Spring Data 对整个数据操作做了很好的封装&#xff0c;其中 Spring Data Common 定义了很多公用的接口和一些相对数据操作的公共实现&#xff08;如分页排序、结果映射、Autiting 信息、事务等&#xff09;&#xff0c;而 Spring Data JPA…

mysql面试题46:MySQL中datetime和timestamp的区别

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL中DATETIME和TIMESTAMP的区别 在MySQL中,DATETIME和TIMESTAMP是两种用于存储日期和时间的数据类型。虽然它们都可以用于存储日期和时间信息…

Java版本+企业电子招投标系统源代码+支持二开+招投标系统+中小型企业采购供应商招投标平台

功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外部供…

大数计算:e^1000/300!

1.问题:大数计算可能超出数据类型范围 当单独计算 ,因为 e^{700} \approx 1.01432*e304" class="mathcode" src="https://latex.csdn.net/eq?e%5E%7B1000%7D%20%3E%20e%5E%7B700%7D%20%5Capprox%201.01432*e304">,double的最大取值为1.79769…

【NeRF】2、NeRF 首篇经典论文介绍(ECCV2020)

文章目录 一、背景二、方法2.1 神经辐射场场景表达3.2 使用辐射场来进行立体重建3.3 优化神经辐射场3.3.1 位置编码3.3.2 分层立体采样3.3.3 具体实现细节 三、效果 论文&#xff1a;Representing Scenes as Neural Radiance Fields for View Synthesis 代码&#xff1a;https…

攻防世界题目练习——Crypto密码新手+引导模式(二)(持续更新)

题目目录 1. 转轮机加密2. easychallenge 上一篇&#xff1a;攻防世界题目练习——Crypto密码新手引导模式&#xff08;一&#xff09;&#xff08;持续更新&#xff09; 1. 转轮机加密 首先了解一下轮转机加密吧。 传统密码学(三)——转轮密码机 题目内容如下&#xff1a; …

通讯录(C语言版)

用c语言实现一个通讯录 功能&#xff1a;.添加、删除、查找、更改、显示、排序联系人 内存存储方式&#xff1a;结构体数组 1.打印菜单&#xff0c;各个功能分别用函数实现&#xff0c;将函数声明放在头文件中。 2.定义联系人信息&#xff0c;将联系人信息与count&#xff…

云渲染是什么?云渲染怎么用?

云渲染的出现为影视动画、建筑设计、游戏开发等领域提供了很大的便利&#xff0c;为公司或者个人节约了大量的渲染部分时间&#xff0c;大大的提高了工作效率。哪什么是云渲染&#xff1f;云渲染怎么用呢&#xff1f;我们一起来看看。 云渲染是什么&#xff1f; 云渲染是一种…

高级深入--day30

Scrapy Shell Scrapy终端是一个交互终端,我们可以在未启动spider的情况下尝试及调试代码,也可以用来测试XPath或CSS表达式,查看他们的工作方式,方便我们爬取的网页中提取的数据。 如果安装了 IPython ,Scrapy终端将使用 IPython (替代标准Python终端)。 IPython 终端与其…

QDir实践

现在有多个文件&#xff0c;路径为&#xff1a; a\xxx\kmd_config\c.json 其中xxx是变量 startcalc,,,,,, 目标&#xff1a; 访问每一个json文件 实例&#xff1a; QString app_path QApplication::applicationDirPath() "/app";QDir dir(app_path);QStringLi…

NewStarCTF2023公开赛道-压缩包们

题目提示是压缩包 用010editor打开&#xff0c;不见PK头&#xff0c;补上50 4B 03 04 14 00 00 00 将文件改成.zip后缀&#xff0c;打开&#xff0c;解压出flag.zip 尝试解压&#xff0c;报错 发现一串base64编码 SSBsaWtlIHNpeC1kaWdpdCBudW1iZXJzIGJlY2F1c2UgdGhleSBhcmUgd…

【LeetCode刷题笔记】二分查找

1539. 第 k 个缺失的正整数 解题思路&#xff1a; 1. 二分 &#xff0c;一个严格升序 正整数 数组在没有数字缺失的情况下满足&#xff1a; nums[i] i 1 &#xff0c;如果有缺失&#xff0c;则每个 下标 i 上的数字前面缺失的正整数个数为&#xff1a; nums[i] - (i 1) &am…

ROS 摄像头标定-camera_calibration

摄像头这种精密仪器对光学器件的要求较高&#xff0c;由于摄像头内部与外部的一些原因&#xff0c;生成的物体图像往往会发生畸变&#xff0c;为了避免数据源造成的误差&#xff0c;需要针对摄像头的参数进行标定。 ROS官方提供了用于双目和单目摄像头标定的功能包—camera_cal…

单链表---结构体实现

定义 链表称为线性表的链式存储&#xff0c;顺序表逻辑上相邻的数据&#xff0c;存储位置也相邻。链表逻辑上相邻的数据&#xff0c;存储位置是随机分布在内存的各个位置上的。 故 对于每一个结点&#xff0c;定义的结构体是&#xff1a; typedef struct _LinkNode {int d…

存档&改造【06】Apex-Fancy-Tree-Select花式树的使用误删页数据还原(根据时间节点导出导入)

之前一直想实现厂区-区域-产线之间的级联选取&#xff0c;于是导入插件Apex-Fancy-Tree-Select花式树 存档&#xff06;改造【03】Apex-Fancy-Tree-Select花式树的导入-CSDN博客 现在则是在Oracle Apex中的应用 花式书级联列表展示厂区-区域-产线 想要实现的效果 由厂区>…

Shopee活动报错怎么办?Shopee活动类型怎么选择?-站斧浏览器

有时候&#xff0c;在同步虾皮活动的过程中&#xff0c;您可能会遇到一些问题或报错信息。遇到这种情况要怎么办&#xff0c;Shopee活动类型怎么选择&#xff1f; Shopee活动报错怎么办&#xff1f; 下面是几种常见的问题及其解决方法&#xff1a; 1、网络连接问题&#xff…

05 | @Query 解决了什么问题?什么时候应该选择它?

上个课时我们介绍了 Query Define Method 的语法&#xff0c;这一课时来介绍一下 Query 注解的语法是什么样的。我们通过快速体验 Query 的方法、JpaQueryLookupStrategy 关键源码剖析、Query 的基本用法、Query 之 Projections 应用返回指定 DTO、Query 动态查询解决方法&…

网工笔记整理:策略工具Filter-policy的使用

一、概述 Filter-Policy&#xff08;过滤-策略&#xff09;是一个很常用的路由信息过滤工具&#xff0c;能够对接收、发布、引入的路由进行过滤&#xff0c;可应用于IS-IS、OSPF、BGP等协议。 Filter-policy在距离矢量路由协议中的应用 filter-policy import&#xff1a;不发…

Python学习基础笔记六十五——布尔值

布尔对象&#xff1a; Python中有一种对象类型称之为布尔对象&#xff08;英文叫bool&#xff09;。 布尔对象只有两种取值&#xff0c;True和False。对应的是真和假&#xff0c;或者说是和否。True对应的是&#xff0c;False对应的是否。 我觉得这句话是一个关键&#xff1a…

04 | 如何利用 Repository 中的方法返回值解决实际问题?

上一课时&#xff0c;我们着重讲了方法名和参数的使用方法&#xff0c;这一课时我们来看下Repository 支持的返回结果有哪些&#xff0c;以及 DTO 类型的返回结果如何自定义&#xff0c;及其在实际工作场景中我们如何做。通过本课时的学习&#xff0c;你将了解到 Repository 的…