既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408162558852.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)
*网络爬虫是伪装成客户端与服务端进行数据交互的程序。那么,客户端和服务端该怎样进行数据交互呢?就像我们中国人用中文交流,说的中国的语法,我们可以正常沟通。客户端与服务端如果不统一一下,那不就乱套了,所以在网络传输方面产生了众多协议,HTTP就是其中一种。*
### (1)HTTP协议
目前互连网上90%的网络传输都是基于http协议(补充:http协议是一个应用层协议)。(注意:爬取想要的数据前,一定要明确其使用的是什么协议!虽然90%都是基于http协议,但是仍有10%采用的是其他的协议,比如:弹幕可能采取的是websocket协议!这样的话,我们采取传统的爬虫就无法爬取到了。)
| |
| --- |
| HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 |
HTTP是基于TCP/IP通信协议来传递数据的(HTML 文件, 图片文件, 查询结果等)。
*注意:TCP/IP有个面向连接的特性!(意义:保证数据的完整性)*
让咱们生动的了解一下TCP/IP通信协议中的三次握手四次挥手:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408164041435.png)
* 三次握手建立连接:
🔑客户端说:嘿,服务端girl!我想和你建立连接。(打招呼)
🔒服务端说:好的呢,我听你的。
🔑客户端说:真好,那咱们开始数据交互吧(羞羞)。
.
.(干羞羞的事ing,进行数据交互)
.
* 四次挥手断开连接:
🔑客户端说:我已经和你交互完数据了,咱断开连接吧!(打招呼)
🔒服务端说:你确定断开连接嘛?(不舍)
🔒服务端又说:那你断开连接吧!
🔑客户端说:好的,那我断开连接了!
### (2)HTTP请求流程:
我们日常用浏览器搜索东西,输入的是URL,浏览器会将其自动转换为HTTP协议。
一次http请求的基本流程是,有客户端向服务端发起一次**请求(request)**, 而服务器在接收到以后返回给客户端一个**响应(response)**。**所以一次完整的http请求包含请求和响应两部分。**
##### 浏览器发送http请求的过程:
1.域名解析 -->
2.发起TCP的3次握手 -->
3.建立TCP连接后发起http请求 -->
4.服务器响应http请求,浏览器得到html代码 -->
5.浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) -->
6.浏览器对页面进行渲染呈现给用户.
知识点补给站:
在网页的右键检查里Network->Name->Request Headers view parsed下
的Connection:keep-alive保持常连接,就不用频繁的三次握手和四次挥手!
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408165114769.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)
>
> 浏览器获取的内容(elements的内容)包含:url地址对应的响应+js+css+pictures
> 爬虫会获取:url地址对应的响应
> 爬虫获取的内容和elements的内容不一样,进行数据提取的时候,需要根据url地址对应的响应为准!
>
>
>
### (3)URL(浏览器搜索框里的内容!)
**发送http请求时,通过url对网络资源进行定位。**
URL(Uniform Resource Locator),中文叫统一资源定位符。是用来标识某一处资源的地址。也即是我们常说的网址。以下面这个URL为例,介绍下普通URL的各部分组成:
协议+域名(端口默认80)+路径+参数
**注意:
1.http协议的端口号默认为80可以不写;https协议的端口号默认为443可以不写(注意:域名可以确定是哪一台电脑;而端口号是为了确定是那台电脑的哪一个应用!)
2.域名通常是IP地址的映射,端口号通常是默认的就不写。我们平常搜索时,比如进入百度:https://www.baidu.com/,这里的https协议的默认端口号为443,就没写哦!**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408165827973.png)
### (4)HTTP请求格式
客户端(也就是我们用户)发送一个HTTP请求到服务器的请求消息包括以下部分:请求行,请求头,空行和请求数据。
**一般格式:**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408173240505.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)
*注意:上图中请求行的URL是指(2)URL中的路径!*
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408173751777.png)
#### 1.请求方法:
###### (1)分类
根据http标准,http请求可以使用多种请求方法。
五种请求方法:OPTIONS,**PUT,DELETE**,TRACE和CONNECT方法。
###### (2)分类讲解
常用方法 是 GET和POST。
* `GET`
1.主要是负责从服务器获取数据
2.URL中添加请求参数,显示在地址栏
3.请求字符串限制 1024个字节
比`POST`更加高效和方便。
* `POST`
1.主要负责向服务器提交数据
2.没有大小限制(但一般是2M)
比’GET’传递数据量大,安全性高。
###### (3)所有请求方法:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408174232772.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)
#### 2.请求头:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210709005148766.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)![在这里插入图片描述](https://img-blog.csdnimg.cn/20210709005216556.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)![在这里插入图片描述](https://img-blog.csdnimg.cn/20210709005230926.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)
#### 3.HTTP请求正文(请求数据)
请求正文通常是使用POST请求中表单数据,而对于GET请求,请求体则为空。
>
> 需要注意的是:
> 在爬虫中,如果要构造POST请求,需要使用正确的Content-Type,并了解各种请求库的各个参数设置时使用的是哪种Content-Type,不然可能会导致POST提交后无法正常响应。
>
>
>
Content-Type和POST提交数据方式的关系
| Content-Type | 提交数据的方式 |
| --- | --- |
| application/x-www-form-urlencoded | 表单数据 |
| multipart/form-data | 表单文件上传 |
| application/json | 序列化JSON数据 |
| text/xml | XML数据 |
请求正文跟上面的消息报头由一个空行隔开。
| |
| --- |
| 来个承上启下!既然现在请求格式已经OK了,也就是说我们可以让服务端听懂我们说的话了;下面要做的就是让我们能听懂服务端给我们说的话了。 |
### (5)HTTP响应格式
HTTP响应也由四个部分组成,分别是:状态行(响应行)、消息报头、空行和响应正文。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408180236767.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70) **一般格式:**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408180345475.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)
#### 1.HTTP响应状态码:(这里面就有熟悉的404哦!)
当客户端向服务端发起一次请求后,服务端在返回的响应头中会包含一个HTTP状态码(我们在进行爬虫实战的时候可以通过判断此状态码得知目前的爬虫代码是否OK!)。
HTTP的状态码是由**三位数字**来表示的,由第一位数字来表示状态码的类型,一般来说有五种类型:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408181026575.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)注意:重定向就相当于一个中介转接。([所有HTTP响应状态码详解点我查看!](https://bbs.csdn.net/topics/618668825))
#### 2.HTTP响应报头:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210709005616979.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)
#### 3.HTTP响应正文:
>
> 这肯定是最重要的啦!响应的正文数据都在响应体中。我们日后做爬虫,要解析的内容就是响应体哦~
>
>
>
---
### (6)总结:
#### 1.HTTP流程总结:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200408181606252.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)
#### 2.HTTP协议的特点:
**HTTP三点注意事项:**
* HTTP是无连接的:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
* HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。
* HTTP是无状态的:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
无状态HTTP官方详解:
HTTP的无状态是指HTTP协议对事务处理是没有记忆能力的,也就是说服务器不知道客户端是什么状态。当我
们向服务器发送请求后,服务器解析此请求,然后返回对应的响应,服务器负责完成这个过程,而且这个过程是完全
独立的,服务器不会记录前后状态的变化,也就是缺少状态记录。这意味着如果后续需要处理前面的信息,则必须重
传,这导致需要额外传递一些前面的重复请求,才能获取后续响应,然而这种效果显然不是我们想要的。为了保持前
后状态,我们肯定不能将前面的请求全部重传一次,这太浪费资源了,对于这种需要用户登录的页面来说,更是棘手。
这时两个用于保持HTTP连接状态的技术就出现了,它们分别是会话和Cookies。下面会介绍到哦!
| |
| --- |
| 注意: 无状态的意思是,比如你再一个网页中输入了账号密码登录了QQ空间,但是由于HTTP是无状态的,所以你再在QQ空间里登录QQ邮箱需要再输入一次账号和密码,登录的状态是没有被记忆的。但是可以利用会话技术解决。 |
#### 3.HTTPS协议:
**加强版的HTTP,公鸡中的战斗机一枚!!!**
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer 或 Hypertext Transfer Protocol Secure,超文本传输安全协议),是以安全为目标的HTTP通道,简单讲是HTTP的安全版!
http协议是基于tcp/ip协议的,而https是在http协议的基础之上,再加了一层**SSL/TLS协议**,数据在传输过程中是加密的。
注意:HTTPS协议的默认端口是443。
http因为是明文传输,而https是密文传输,所以HTTPS比http更安全,
但是性能低,因为解密需要消耗时间!
## 3.解决http无状态 之 会话技术
**http是无状态的,那服务端怎么区分同一个用户的连续请求呢,这就用到了会话技术:cookie和session。**
会话在服务端,也就是网站的服务器,用来保存用户的会话信息;Cookies在客户端,也可以理解为浏览器端。有了Cookies,浏览器在下次访问网页时就会自动附带上它发送给服务器,服务器通过识别Cookies并鉴定出是哪个用户,然后再判断用户是否是登录状态,然后返回对应的响应。
### (1)Cookie
**Cookie有时也用其复数形式 Cookies。**
指某些网站为了辨别用户身份、进行 session 跟踪而储存在**用户本地终端上**的数据(通常经过加密)。最新的规范是 RFC6265 。
**Cookie可以理解为一个凭证**
* 1.实际是由服务器发给客户端的特殊信息,
* 2.这些信息以文本文件的方式存放在客户端,
* 3.客户端每次向服务器发送请求的时候都会带上这些特殊的信息。
* 4.服务器在接收到Cookie以后,会验证Cookie的信息,以此来辨别用户的身份。
**爬虫中为什么要使用cookie?**
1. 带上cookie的好处:
①能够访问登录页面。
②正常的浏览器在请求服务器的时候肯定会带上cookie(第一次请求除外),所以对方服务器有可能会通过是否携带cookie来判断我们是否是一个爬虫,对应的能够起到一定的反爬作用。
2. 带上cookie的坏处:
①一套cookie往往对应的是一个用户的信息,请求太频繁有更大的可能性被对方识别为爬虫。
②一般使用多账号解决。
### (2)Session
**Session,中文经常翻译为会话,** 其本来的含义是指有始有终的一系列动作/消息,比如打电话时从拿起电话拨号到挂断电话这中间的一系列过程可以称之为一个session。这个词在各个领域都有在使用。
而我们web&爬虫领域,一般使用的是其本义,**一个浏览器窗口从打开到关闭这个期间。**
**Session的目的则是,在一个客户从打开浏览器到关闭浏览器这个期间内,发起的所有请求都可以被识别为同一个用户。** 而实现的方式则是,在一个客户打开浏览器开始访问网站的时候,会生成一个cookie,SessionID(注意:SessionID包含于cookie中),这个ID每次的访问都会带上,而服务器会识别这个SessionID并且将与这个SessionID有关的数据保存在服务器上。由此来实现客户端的状态识别。**因此session是基于cookie的!**
Session与Cookie相反,**Session是存储在服务器上的数据**,只由客户端传上来的SessionId来进行判定,**所以相对于Cookie,Session的安全性更高。**
一般SessionID会在浏览器被关闭时丢弃,或者服务器会验证Session的活跃程度,例如30分钟某一个SessionID都没有活跃,那么也会被识别为失效。
session的作用——用来实现客户端和服务的的会话保持!
会话(状态)保持:①保存cookie;② 实现和服务端的长连接。
### (3)cookie和session的区别:
1. cookie数据存放在客户的浏览器上,session数据放在服务器上;
2. cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗;
3. session会在一定时间内保存在服务器上,当访问增多,会比较占用服务器的性能;
4. 单个cookie保存的数据不能超过4k,很多浏览器都限制一个站点最多保存20个cookie。
### (4)来个图理解理解那么枯燥的文字:
**用户首次登录时:**
会在服务器生成一个session表,里面的key是hash生成的数据,value是一系列信息。
同时在客户端本地生成一个文本文件cookie,这里面包含sessionid,而这个sessionid的值为服务器中的hash形式的key。
![在这里插入图片描述](https://img-blog.csdnimg.cn/f9b02cb4b2414ba098be89a712bfde95.png)
**用户再次登录时:**
会自动携带sessionid及其值,这个值与服务器里的hash形式的key比较,判断用户是否曾登录成功,如果成功,则获取用户登录的数据,然后返回给用户请求的界面。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20121bb7078343a4a82c727fa01c7641.png)
### (5)实操一波看看Cookies的属性结构:
**(以QQ空间为例!)**
F12打开浏览器开发者工具,然后按如图步骤即为Cookies:(可以看到有很多条目,其中每个条目可以称为Cookie。)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20466c1663414aacb0a5c75c76b71d1d.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)
| 属性名 | 属性值讲解 |
| --- | --- |
| Name | 该Cookie的名称。一旦创建,无法修改! |
| Value | 该Cookie的值。如果值为Unicode字符,需要为字符编码;如果值为二进制数据,则需要使用BASE64编码。 |
| Domain | 可以访问该Cookie的域名。 |
| Max Age | 该Cookie失效的时间,单位为S,通常和Expires一起使用,通过它可以计算出其有效时间。Max Age如果为正数,则该Cookie在Max Age秒后失效;如果为负数,则关闭浏览器时失效,浏览器也不会以任何形式保存该Cookie。 |
| Path | 该Cookie的使用路径。如果设置为/path/,则只有路径为/path/的页面可以访问该Cookie;如果设置为/,则本域名下的所有页面都可以访问该Cookie。 |
| Size | 此Cookie的大小。 |
| HTTP字段 | Cookie的httponly属性。若此属性为true,则只有在HTTP头中会带有此Cookie 的信息,而不能通过document.cookie来访问此Cookie。 |
| Secure | 该Cookie是否仅被使用安全协议传输。安全协议有HTTPS和SSL等,在网络上传输数据之前先将数据加密。默认为false。 |
## 4.爬虫实战:利用socket下载一张图片
### (1)socket学习
**socket国外翻译为插座;同时,由于其具备了“套接”和“字”的概念,所以又称为套接字。**
![在这里插入图片描述](https://img-blog.csdnimg.cn/9a4c02e0c67b491a84b3c42cf4bac4ef.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200409180244497.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/9f07460a994a44baa823319c87b83a33.png)
知识补给站:(混个眼熟就行了!)
Socket是一种进程间通信机制,提供一种供应用程序
访问通信协议的操作系统调用,使得网络读写数据
和读写本地文件一样容易;Socket是一序列的“指令” ;
已经具备了“套接”(建立网络通讯或进程间通讯)和“字”(可交互的有序指令串)的概念。
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020040819035763.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0OTA3OTI2,size_16,color_FFFFFF,t_70)
#### ①使用socket简单建造一个服务端:
* ([点我观看另一篇进阶版搭建的TCP服务器端文章](https://bbs.csdn.net/topics/618668825))
import socket
服务器对象
server = socket.socket()
‘’’
等同于:server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.AF_INET:使用IPV4;
socket.SOCK_STREAM:创建一个socket套接字。
‘’’
1.绑定服务器
server.bind((“0.0.0.0”,8800)) #0.0.0.0是允许所有人来访问;8800是端口号
2.监听
server.listen(5)
while True:
# 3.等待连接
# accept是一个阻塞的方法(你不来我就不动!),等待连接,每建立一个连接就会创建一个单独的通道。
# conn:通道参数;addr:通道地址。
conn,addr=server.accept()
# 4.接收数据
data=conn.recv(1024)
print(data)
response="HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf-8;\r\n\r\n<h1 style='color:black'>我很帅!<h1>"
# 5.发送数据
conn.send(response.encode())
print("已经响应")
6.关闭
server.close()
**在本地浏览器中输入:127.0.0.1:8800即可访问到此服务端:**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200501120209502.png)
#### ②使用socket简单建造一个客户端:(爬取百度首页整个界面)
import socket
建立服务器对象 通过打印这个client服务器对象可知:默认使用的是IPV4,协议是TCP。
client=socket.socket()
1.建立连接
client.connect((“www.baidu.com”,80))
构造请求报文
data=b"GET / HTTP/1.1\r\nHost: www.baidu.com\r\n\r\n"
2.发送请求
client.send(data)
res=b""
3.接收数据
temp=client.recv(4096)
while temp:
print(“*”*50)
res += temp
temp = client.recv(4096)
print(temp.decode())
4.断开连接
client.close()
### (2)实战:使用socket来爬取一张漂亮MM的图片:
利用谷歌浏览器分析:
![在这里插入图片描述](https://img-blog.csdnimg.cn/079f5dc4e31640969d5e9157e210f222.png)
**据说搜狗是没有设置反爬的,刚入门的话就挑软柿子捏,所以我们就来爬爬它。**
###### 1.首先,分析网页:
![请添加图片描述](https://img-blog.csdnimg.cn/ea525be1b42f41b9bd3b81ed910b267a.png)
**而我们要爬取的图片的URL就在头信息里的Request URL中。CV大法即可!**
###### 2.上代码:
![img](https://img-blog.csdnimg.cn/img_convert/5ae5f10754dea4970403ff4656a21f58.png)
![img](https://img-blog.csdnimg.cn/img_convert/61f763fe7f0c7af8baa1bd338cbd65ce.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
**据说搜狗是没有设置反爬的,刚入门的话就挑软柿子捏,所以我们就来爬爬它。**
###### 1.首先,分析网页:
![请添加图片描述](https://img-blog.csdnimg.cn/ea525be1b42f41b9bd3b81ed910b267a.png)
**而我们要爬取的图片的URL就在头信息里的Request URL中。CV大法即可!**
###### 2.上代码:
[外链图片转存中...(img-qqsils1x-1715794869929)]
[外链图片转存中...(img-kdzFdDgM-1715794869930)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**