首页 > 编程语言 >对C++做爬虫的代码进行简单分析

对C++做爬虫的代码进行简单分析

时间:2023-03-10 23:14:54浏览次数:41  
标签:函数 filePath url 代码 爬虫 C++ TCHAR 编译器

有这样一段代码

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include<urlmon.h>
#pragma comment(lib, "urlmon.lib")

int main() {
	TCHAR url[] = TEXT("https://img.paulzzh.tech/touhou/random?site=all&size=all");//一个很正常向的东方project图片API
	TCHAR filePath[] = _T("祖传色图.jpg");
	HRESULT res = URLDownloadToFile(NULL, url, filePath, 0, NULL);
	if (res == S_OK) {
		printf("色图Ok,单击任意键以退出喵\n");
		system("pause");
	}
	else if (res == E_OUTOFMEMORY) {
		printf("你的电脑内存不足喵\n");
		system("pause");
	}
	else if (res == INET_E_DOWNLOAD_FAILURE) {
		printf("色图服务器挂了喵\n");
		system("pause");
	}
	else {
		printf("Other error: %d\n", res);
		system("pause");
	}
	return 0;
}

这段代码使用了 URLDownloadToFile 函数从指定 url 下载文件到本地电脑,具体来说:

1.导入了 stdio.h、 tchar.h、 windows.h 和 urlmon.h 头文件,其中 urlmon.h 声明了 URLDownloadToFile 函数,通过 #pragma comment(lib, "urlmon.lib") 链接库文件。

2.定义了一个 TCHAR 类型的 url 指针变量,用于存储下载图片的 url。

3.定义了一个 TCHAR 类型的 filePath 指针变量,用于指定下载后保存的文件路径。

4.调用 URLDownloadToFile 函数,它的四个参数分别是:

  • 用于控制 url 连接的 LPUNKNOWN 指针,这里传入 NULL。
  • 要下载的文件 url,即上一步定义的 url 变量。
  • 要保存到本地的文件路径,即上一步定义的 filePath 变量。
  • 用于显示下载进度和其他信息的 DWORD 类型指针,这里传入 NULL。
    5.根据函数返回值判断下载是否成功,返回值有几种情况,分别对应不同的错误情况,这里设置了三种情况的处理方式:
  • S_OK 表示下载成功,输出 "色图Ok,单击任意键以退出喵"。
  • E_OUTOFMEMORY 表示内存不足,输出 "你的电脑内存不足喵"。
  • INET_E_DOWNLOAD_FAILURE 表示下载失败,输出 "色图服务器挂了喵"。
  • 其他情况输出 "Other error: " 后接错误值。
    6.返回 0,程序结束。
    总的来说,这段代码的作用是从指定 url 下载指定图片,并处理下载过程中可能遇到的错误情况。

Q:

#include<urlmon.h>
#pragma comment(lib, "urlmon.lib")

A:
这两行代码的作用是使用 urlmon.h 头文件中定义的函数,并将 urlmon.lib 库文件链接到程序中。

#include<urlmon.h>:该头文件包含了许多与网络相关的函数和常量,例如常用的 URLDownloadToFile 函数,用于从互联网上下载文件,使得在 C/C++ 语言中处理网络操作更加方便。

#pragma comment(lib, "urlmon.lib"):这行代码告诉链接器,在链接时将 urlmon.lib 库文件链接到可执行文件中,使得程序在运行时可以正确调用 urlmon.h 头文件所定义的 API 函数。可以看作是编译器通过指定链接器选项,告诉链接器在本程序中加入某种库文件的一种简便方法,避免了手动在编译器选项中设置链接器参数。

一般地,只要是要使用某一个库文件(比如链接器库文件),就需要使用 #pragma comment 语句将该库文件链接到程序中,使得程序在运行时可以正确调用引入库的 API 函数或数据。

另外,需要注意的是,在使用 #pragma comment 语句指示链接器链接库文件时,要保证库文件已经正确安装在包含该头文件的开发环境中。否则在编译或链接时可能会出现错误。

Q:
代码中的TCHAR是干什么的

A:
TCHAR 是在 Windows 平台下为处理 Unicode 和 ANSI 字符集转换而定义的一个宏,具体是根据编译时定义的 _UNICODE 预处理宏来决定其实际指向的类型,是 wchar_t 类型或 char 类型的两者之一,方便编程者在不同编译环境下编写跨平台的代码。

在 Windows 系统中,通常情况下字符集会有 ANSI(A)和 Unicode(W)两套实现,对应着带字符串后缀的函数和宏。例如:strcmp 和 strstr 是 ANSI 字符集下的字符串处理函数,而 wcscmp 和 wcsstr 则是 Unicode 字符集下的字符串处理函数,通过宏变量 TCHAR 的定义,可以根据编译器的预处理指令选择使用相应的字符集。

在这个代码中,TCHAR 用于定义字符串类型,使得可以根据编译器预处理器指令决定是使用 Unicode 字符集还是 ANSI 字符集。在该代码中,通过 TEXT 宏,使用了 TCHAR 类型的变量 url 和 filePath,分别存储了下载文件的 URL 地址和文件保存的路径,后续调用 URLDownloadToFile 函数时作为函数参数传入,以完成从指定 URL 下载文件并将其保存到本地电脑的目的。

Q:
TCHAR filePath[] = _T("祖传色图.jpg"); 这个_T是什么意思

A:
_T 是 Visual Studio 中的一个宏,它可以让同一个代码在不同的编译器下正确地处理字符串, 它实际上就是根据不同的编译器预处理器指令来决定是使用 Unicode 字符串还是 ANSI 字符串。在 Unicode 编译器下, _T 宏会将字符串常量添加一个 L 前缀,表示使用的是 Unicode 格式的字符串,否则不会添加 L 前缀,表示使用的是 ANSI 格式的字符串。

在本代码中,TCHAR 也是一个由编译器预处理器决定的宏,如果在代码头文件中定义了 _UNICODE 宏,它就会被预处理为 wchar_t 类型,表示使用的是 Unicode 字符集;如果没有定义 _UNICODE 宏,则 TCHAR 会被预处理为 char 类型,表示使用的是 ANSI 字符集。

综合来看,_T 宏为了保证代码可以在 Unicode 和 ANSI 编译器下都可以工作。在这个代码中,TCHAR filePath[] = _T("祖传色图.jpg"); 可以根据编译器预处理器的设置,自动将字符串常量 祖传色图.jpg 转换为适合的格式,并赋值给 filePath 变量。如果预处理器指定使用 Unicode 编译器,则 TCHAR 宏会被预处理为 wchar_t 类型,则 filePath 也会被定义为 wchar_t 类型的数组,并接收 Unicode 字符串;如果预处理器指定使用 ANSI 编译器,则 TCHAR 宏不起作用,filePath 也会被定义为 char 类型的数组,并接收 ANSI 字符串。

Q:
那这代码中,我不用TCHAR行不行

A:
使用 TCHAR 并不是必须的,你可以使用 char 或者 wchar_t 来代替 TCHAR,只需要保证字符集的一致性即可。比如,在该代码中,你可以将声明 TCHAR url[] 和 TCHAR filePath[] 的语句改写如下:

char* url = "https://img.paulzzh.tech/touhou/random?site=all&size=all";
char* filePath = "祖传色图.jpg";

或者

wchar_t* url = L"https://img.paulzzh.tech/touhou/random?site=all&size=all";
wchar_t* filePath = L"祖传色图.jpg";

这样就不需要使用 TCHAR 宏和 _T 宏了,而是直接使用 char 或者 wchar_t 类型来定义变量了。但是需要注意的是,如果你的程序需要在不同编译器之间进行兼容,建议使用 TCHAR 和 _T 这种跨平台兼容的方式实现。

Q:
那HRESULT又是什么意思呢

A:
HRESULT 是指 Windows 操作系统中的错误代码规范(Error Codes),它是由 32 位值构成,以表示返回结果的一种数据类型。HRESULT 具体用于描述函数或方法调用的状态和结果,同时包含了三个部分的信息:位 0-10 表示错误 Facilty;位 11-15 表示错误的级别 Severity;位 16-31 表示具体错误代码 Code。

在该代码中,HRESULT 类型的变量 res 用于存储函数 URLDownloadToFile 的返回值(函数的返回值类型为 HRESULT),以根据不同的返回值来表明不同的下载状态。具体来说:

如果函数返回值 res 等于 S_OK,表示下载成功;
如果函数返回值 res 等于 E_OUTOFMEMORY,表示内存不足;
如果函数返回值 res 等于 INET_E_DOWNLOAD_FAILURE,表示下载文件失败;
如果函数返回值不是以上三种情况,则表示发生了其他未知错误,此时会调用 printf 函数,输出其他错误码的信息。
一般情况下,在 Windows 编程中,函数的返回值类型为 HRESULT,并且根据返回值来进行错误码处理非常常见,使用 HRESULT 可以方便地表达函数调用的状态和结果,帮助程序员在开发和调试时快速定位问题。

标签:函数,filePath,url,代码,爬虫,C++,TCHAR,编译器
From: https://www.cnblogs.com/wozhuyinghao/p/17204919.html

相关文章

  • C# 调用 c++ DLLL试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B
     网上各种设置目标编译平台为x86都解决不了问题,有可能是DLL依赖的文件的位数有问题1、先查一下被调用的DLL用了那些DLLvs的开发人员工具控制台输入 dumpbin/depe......
  • 代码随想录day24|回溯基础、77. 组合
    回溯法,一般可以解决如下几种问题:组合问题:N个数里面按一定规则找出k个数的集合切割问题:一个字符串按一定规则有几种切割方式子集问题:一个N个数的集合里有多少符合条件的......
  • C++ 标准库中的 vector
    标准库类型vector表示对象的集合,其中所有对象的类型都相同。集合中的每个对象,都有一个与之对应的索引,索引用于访问对象。vector是一个类模板,编译器根据模板创建类或者函......
  • C++ | 計算兩點的角度
    #include<math.h>#include<iostream>#include<stdio.h>#definePI3.141592654#defineEARTH_RADIUS6378.137//地球近似半徑u......
  • C++协程
    参考C++那些事之C++20协程#include<iostream>#include<coroutine>structgenerator{structpromise_type{intcurrent_value;std::suspend......
  • python爬虫获取国家统计局区划代码和城乡划分代码添加到数据库
    importpymysqlfrombs4importBeautifulSoupimportrequestsimporttimefromlxmlimportetreedefget_area(year):year=str(year)url="http://ww......
  • 代码随想录-数组
    二分查找704.二分查找-力扣(LeetCode)intsearch(int*nums,intnumsSize,inttarget){intleft=0;intright=numsSize-1;intmid=0;i......
  • JS代码加密:Eval的终极用法
    Eval加密的终极用法Eval加密,做为一种传统且古老的JS代码加密方法,相信很多人都知道。例如这个在线Eval加密:​​https://www.fairysoftware.com/js_jia_mi_eval.html​​但这......
  • 网络爬虫-爬取豆瓣Top250
    一、选题的背景(10分)本次爬取的内容是豆瓣网站平均评分第一名到第二百五十名的电影名称,电影链接,电影封面图片链接,电影的概况和电影的相关信息。现在电影是人们一种很普遍的......
  • 代码随想录算法Day38 | 动态规划理论基础 ,509. 斐波那契数 ,70. 爬楼梯 ,746. 使用最
    动态规划理论基础动态规划五步曲:确定dp数组(dptable)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组509.斐波那契数题目链接:509.斐......