最近看了一个 pinterest 上的一段短视频 https://www.pinterest.com/ 虽然从爬虫角度来看,要下载并没有什么难得地方,pinterest 网站的接口做得也很开放,大概看看视频页面 html 找找接口,然后 requests 很容易就可以做
不过,我想用 c++ 爬。。。然后遇到一些问题。
首先是代理问题,如果用的 socks ,要自己开启全局代理,那 cpprest 怎么做才能使用 ss 代理呢?我运气很好的在 cpprest 的 github 上找到了方法,这是他们的做代理测试的文件(https://github.com/Microsoft/cpprestsdk/blob/master/Release/tests/functional/http/client/proxy_tests.cpp),然后看到了这段代码:

所以,只需要这样写就可以使用全局代理:
http_client_config cfg;
cfg.set_proxy(web_proxy::use_auto_discovery);
http_client raw_client(U("https://www.pinterest.com/"), cfg);
但接下来就遇到一个问题一直没解决,现在可以正常使用代码请求 pinterest 页面了,但获取到的响应主体部分我不确定 cpprest 内置的gzip、flate、br 压缩 / 解压缩算法有没有在获取到响应主体时开始解压数据(还是说要自己用压缩算法库来解压?),总之结果看起来像是没有:

当然,最开始我没有直接写入文件,而是使用:
resp.extract_string()
来提取数据,却发生了异常。

这样使用:
resp.extract_utf8string()
得到结果:

然后,我也试过这样使用解压库:
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <boost/regex.hpp>
#include <chrono>
#pragma comment(lib, "C:/Program Files/boost_1_72_0/stage/lib/libboost_regex-vc142-mt-gd-x64-1_72.lib")
#pragma comment(lib, "C:/cpprestsdk/Build_x64/Binaries/Debug/cpprest142_2_10d.lib")
using namespace utility;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace web::http::compression;
using namespace concurrency::streams;
int main()
{
http_client_config cfg;
cfg.set_proxy(web_proxy::use_auto_discovery);
cfg.set_timeout(std::chrono::seconds(120));
http_client raw_client(U("https://www.pinterest.com/pin/xxx/"), cfg);
http_request request(methods::GET);
request.headers().add(header_names::accept, L"text/html");
request.headers().add(header_names::user_agent, L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36");
request.headers().add(header_names::accept_encoding, L"gzip, deflate, br");
request.headers().add(header_names::host, L"www.pinterest.com");
request.headers().add(header_names::referer, L"https://www.pinterest.com/");
request.headers().add(L"Connection", L"keep-alive");
// 添加算法库
std::vector<std::shared_ptr<decompress_factory>> dfactories;
dfactories.push_back(builtin::get_decompress_factory(builtin::algorithm::GZIP));
//dfactories.push_back(builtin::get_decompress_factory(builtin::algorithm::DEFLATE));
//dfactories.push_back(builtin::get_decompress_factory(builtin::algorithm::BROTLI));
// 设置解压算法工厂
request.set_decompress_factories(dfactories);
pplx::task<void> requestTask = raw_client.request(request)
.then([=](http_response resp)
{
status_code code = resp.status_code();
std::cout << code << std::endl;
if (code == status_codes::OK)
{
return resp.extract_utf8string();
//return resp.body().extract<std::wstring>();
}
return Concurrency::task<std::string>();
})
.then([=](std::string res)
{
std::cout << res << std::endl;
//wchar_t* output = new wchar_t[];
//compression::decompress_provider::decompress((uint8_t*)res.c_str(), res.size(), (uint8_t*)output, 0, compression::operation_hint::has_more);
boost::regex exp("https?://v.pinimg.com/.*.mp4");
boost::match_results<const char*> ret;
boost::regex_search((char*)res.c_str(), ret, exp);
std::cout << ret.base() << std::endl;
});
try
{
requestTask.wait();
}
catch (const std::exception& e)
{
printf("Error exception:%s
", e.what());
}
return 0;
}
但没啥用。。。