C++ REST图片下载

GitHub - microsoft/cpprestsdk: The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

handler.h

cpp 复制代码
//hander.h
#ifndef HANDLER_H
#define HANDLER_H
#include <iostream>
#include "stdafx.h"
//#include "../dbms/include/Dbms.h"
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <cpprest/http_listener.h>              // HTTP server
#include <cpprest/json.h>                       // JSON library
#include <cpprest/uri.h>                        // URI library
#include <cpprest/ws_client.h>                  // WebSocket client
#include <cpprest/containerstream.h>            // Async streams backed by STL containers
#include <cpprest/interopstream.h>              // Bridges for integrating Async streams with STL and WinRT streams
#include <cpprest/rawptrstream.h>               // Async streams backed by raw pointer to memory
#include <cpprest/producerconsumerstream.h>     // Async streams for producer consumer scenarios

using namespace std;
using namespace web;
using namespace http;
using namespace utility;
using namespace http::experimental::listener;


class handler
{
public:
	handler();
	handler(utility::string_t url);
	virtual ~handler();

	pplx::task<void>open() { return m_listener.open(); }
	pplx::task<void>close() { return m_listener.close(); }

protected:

private:
	void handle_get(http_request message);
	void handle_put(http_request message);
	void handle_post(http_request message);
	void handle_delete(http_request message);
	void handle_error(pplx::task<void>& t);
	http_listener m_listener;
};

#endif // HANDLER_H

handler.cpp

cpp 复制代码
//hander.cpp
#include "stdafx.h"
#include "handler.h"

handler::handler()
{
    //ctor
}
handler::handler(utility::string_t url) :m_listener(url)
{
    m_listener.support(methods::GET, std::bind(&handler::handle_get, this, std::placeholders::_1));
    m_listener.support(methods::PUT, std::bind(&handler::handle_put, this, std::placeholders::_1));
    m_listener.support(methods::POST, std::bind(&handler::handle_post, this, std::placeholders::_1));
    m_listener.support(methods::DEL, std::bind(&handler::handle_delete, this, std::placeholders::_1));

}
handler::~handler()
{
    //dtor
}

void handler::handle_error(pplx::task<void>& t)
{
    try
    {
        t.get();
    }
    catch (...)
    {
        // Ignore the error, Log it if a logger is available
    }
}


//
// Get Request 
//
void handler::handle_get(http_request message)
{
    ucout << message.to_string() << endl;

    auto paths = http::uri::split_path(http::uri::decode(message.relative_uri().path()));

    message.relative_uri().path();
    //Dbms* d  = new Dbms();
    //d->connect();

    concurrency::streams::fstream::open_istream(U("static/index.html"), std::ios::in).then([=](concurrency::streams::istream is)
    {
        message.reply(status_codes::OK, is, U("text/html"))
            .then([](pplx::task<void> t)
        {
            try {
                t.get();
            }
            catch (...) {
                //
            }
        });
    }).then([=](pplx::task<void>t)
    {
        try {
            t.get();
        }
        catch (...) {
            message.reply(status_codes::InternalError, U("INTERNAL ERROR "));
        }
    });

    return;

};

//
// A POST request
//
void handler::handle_post(http_request message)
{
    ucout << message.to_string() << endl;


    message.reply(status_codes::OK, message.to_string());
    return;
};

//
// A DELETE request
//
void handler::handle_delete(http_request message)
{
    ucout << message.to_string() << endl;

    wstring rep = U("WRITE YOUR OWN DELETE OPERATION");
    message.reply(status_codes::OK, rep);
    return;
};


//
// A PUT request 
//
void handler::handle_put(http_request message)
{
    ucout << message.to_string() << endl;
    wstring rep = U("WRITE YOUR OWN PUT OPERATION");
    message.reply(status_codes::OK, rep);
    return;
};

example.cpp

cpp 复制代码
// example.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include "stdafx.h"
#include "handler.h"
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <cpprest/http_listener.h>              // HTTP server
#include <cpprest/json.h>                       // JSON library
#include <cpprest/uri.h>                        // URI library
#include <cpprest/ws_client.h>                  // WebSocket client
#include <cpprest/containerstream.h>            // Async streams backed by STL containers
#include <cpprest/interopstream.h>              // Bridges for integrating Async streams with STL and WinRT streams
#include <cpprest/rawptrstream.h>               // Async streams backed by raw pointer to memory
#include <cpprest/producerconsumerstream.h>     // Async streams for producer consumer scenarios

using namespace std;
using namespace web;
using namespace http;
using namespace utility;
using namespace http::experimental::listener;




std::unique_ptr<handler> g_httpHandler;

void on_initialize(const string_t& address)
{


	uri_builder uri(address);


	auto addr = uri.to_uri().to_string();
	g_httpHandler = std::unique_ptr<handler>(new handler(addr));
	g_httpHandler->open().wait();

	ucout << utility::string_t(U("Listening for requests at: ")) << addr << std::endl;

	return;
}

void on_shutdown()
{
	g_httpHandler->close().wait();
	return;
}

#ifdef _WIN32
int wmain(int argc, wchar_t *argv[])
#else
int main(int argc, char *argv[])
#endif
{
	utility::string_t port = U("34568");
	if (argc == 2)
	{
		port = argv[1];
	}

	utility::string_t address = U("http://127.0.0.1:");
	address.append(port);

	on_initialize(address);
	std::cout << "Press ENTER to exit." << std::endl;

	std::string line;
	std::getline(std::cin, line);

	on_shutdown();
	return 0;
}

图片下载

cpp 复制代码
// crawlerImg.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
//#include <cpprest/http_client.h>
//#include <cpprest/filestream.h>
//
//using namespace utility;                    // Common utilities like string conversions
//using namespace web;                        // Common features like URIs.
//using namespace web::http;                  // Common HTTP functionality
//using namespace web::http::client;          // HTTP client features
//using namespace concurrency::streams;       // Asynchronous streams
//
//int main(int argc, char* argv[])
//{
//	auto fileStream = std::make_shared<ostream>();
//
//	// Open stream to output file.
//	pplx::task<void> requestTask = fstream::open_ostream(U("results.html")).then([=](ostream outFile)
//	{
//		*fileStream = outFile;
//
//		// Create http_client to send the request.
//		http_client client(U("http://www.bing.com/"));
//
//		// Build request URI and start the request.
//		uri_builder builder(U("/search"));
//		builder.append_query(U("q"), U("cpprestsdk github"));
//		return client.request(methods::GET, builder.to_string());
//	})
//
//		// Handle response headers arriving.
//		.then([=](http_response response)
//	{
//		printf("Received response status code:%u\n", response.status_code());
//
//		// Write response body into the file.
//		return response.body().read_to_end(fileStream->streambuf());
//	})
//
//		// Close the file stream.
//		.then([=](size_t)
//	{
//		return fileStream->close();
//	});
//
//	// Wait for all the outstanding I/O to complete and handle any exceptions
//	try
//	{
//		requestTask.wait();
//	}
//	catch (const std::exception &e)
//	{
//		printf("Error exception:%s\n", e.what());
//	}
//

	//同步方式
	//auto fileStream = std::make_shared<ostream>();
	//ostream outFile = fstream::open_ostream(U("results.html")).get();
	//*fileStream = outFile;

	 Create http_client to send the request.
	//http_client client(U("http://www.bing.com/"));

	 Build request URI and start the request.
	//uri_builder builder(U("/search"));
	//builder.append_query(U("q"), U("cpprestsdk github"));
	//http_response response = client.request(methods::GET, builder.to_string()).get();
	 Write response body into the file.
	//response.body().read_to_end(fileStream->streambuf()).get();
	//fileStream->close().get();
//	return 0;
//}

//访问一个网站并将该内容保存在results.html里面,这里用到了微软自家的PPL并行计算库


#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <memory>
#include <regex>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <cpprest/containerstream.h>

// 请求并解析url
bool get_result(const std::string& url, const std::string& pattern, std::vector<std::string>& vec)
{
	try
	{
		web::http::client::http_client client(web::uri(utility::conversions::to_string_t(url)));
		web::http::http_response response = client.request(web::http::methods::GET).get();

		concurrency::streams::stringstreambuf buffer;
		response.body().read_to_end(buffer).get();
		std::string& str = buffer.collection();

		// 使用C++11提供的正则表达式库
		std::regex r(pattern);
		for (std::sregex_iterator iter(str.begin(), str.end(), r), end; iter != end; ++iter)
		{
			std::cout << iter->str() << std::endl;
			vec.emplace_back(iter->str());
		}
	}
	catch (std::exception& e)
	{
		std::cout << "Exception: " << e.what() << std::endl;
		return false;
	}

	return true;
}

// 获取图片
bool get_result(const std::string& url, std::string& picture)
{
	try
	{
		web::http::client::http_client client(web::uri(utility::conversions::to_string_t(url)));
		web::http::http_response response = client.request(web::http::methods::GET).get();

		concurrency::streams::stringstreambuf buffer;
		response.body().read_to_end(buffer).get();
		picture = buffer.collection();
	}
	catch (std::exception& e)
	{
		std::cout << "Exception: " << e.what() << std::endl;
		return false;
	}

	return true;
}

// 保存图片
bool write_to_file(const std::string& file_path, const std::string& data)
{
	try
	{
		std::ofstream file;
		file.open(file_path, std::ios::out | std::ios::binary);
		if (!file.good())
		{
			return false;
		}
		file.write(data.c_str(), data.size());
		file.close();
	}
	catch (std::exception& e)
	{
		std::cout << "Exception: " << e.what() << std::endl;
		return false;
	}

	return true;
}

int main()
{
	// [1] 请求每一页,将子页面的url保存在sub_url_vec里面
	std::vector<std::string> sub_url_vec;
	std::string pattern = "/desk/[0-9]+.htm";
	for (int i = 1; i <= 32; ++i)
	{
		// 创意主题
		std::string url = "http://www.51ztzj.com/dbizhi/category_27_" + std::to_string(i) + ".htm#content_anchor";
		std::cout << "Start get " << i << " page, url: " << url << std::endl;
		// 请求并解析url
		if (!get_result(url, pattern, sub_url_vec))
		{
			std::cout << "Get " << i << " page failed" << std::endl;
		}
	}

	// 最终的图片url:http://img.51ztzj.com//upload/image/20130220/2013022014_670x419.jpg
	// [2] 将子页面的图片url解析出来放入picture_url_vec
	std::vector<std::string> picture_url_vec;
	pattern = "http://img.51ztzj.com//upload/image/.+/.+_670x419.jpg";
	for (std::size_t i = 0; i < sub_url_vec.size(); ++i)
	{
		std::string url = "http://www.51ztzj.com" + sub_url_vec[i];
		std::cout << "Start get " << i + 1 << " sub page, url: " << url << std::endl;
		// 请求并解析url
		if (!get_result(url, pattern, picture_url_vec))
		{
			std::cout << "Get " << i + 1 << " sub page failed" << std::endl;
		}
	}

	// [3] 最后遍历picture_url_vec,然后一个一个的下载图片
	for (std::size_t i = 0; i < picture_url_vec.size(); ++i)
	{
		std::cout << "Start download " << i + 1 << " picture, url: " << picture_url_vec[i] << std::endl;
		std::string picture;
		// 获取图片
		if (!get_result(picture_url_vec[i], picture))
		{
			std::cout << "Download " << i + 1 << " picture failed" << std::endl;
		}

		std::string file_path = "./download/" + std::to_string(i) + ".jpg";
		// 保存图片
		if (!write_to_file(file_path, picture))
		{
			std::cout << "Write to file failed: " << i + 1 << std::endl;
		}
	}

	return 0;
}

创作不易,小小的支持一下吧!

相关推荐
2401_857439691 小时前
SSM 架构下 Vue 电脑测评系统:为电脑性能评估赋能
开发语言·php
SoraLuna2 小时前
「Mac畅玩鸿蒙与硬件47」UI互动应用篇24 - 虚拟音乐控制台
开发语言·macos·ui·华为·harmonyos
xlsw_2 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
Dream_Snowar3 小时前
速通Python 第三节
开发语言·python
唐诺3 小时前
几种广泛使用的 C++ 编译器
c++·编译器
高山我梦口香糖4 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
冷眼看人间恩怨4 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
信号处理学渣4 小时前
matlab画图,选择性显示legend标签
开发语言·matlab
红龙创客4 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin4 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin