第二部分 爬虫要具备的基础知识

一、HTTP基本原理

(一) URI和URL
        URI全称为:Uniform Resource Identifier,统一资源标志符
        URL全称为:Universal Resource Locator ,即统一资源定位符。
        用URL/URI来唯一指定它的访问方式,包括了访问协议https、访问路径(/即根目录)和资源名称。
        URL是URI的子集,每个URL都是URI,但不是每个URI都是URL。
        URI还有一个子类是URN,全称是:Universal Resource Name,统一资源名称。
  URN只命令资源不指定如何定位资源,比如:urn:isbn:045512345指定一本书的ISBN,可以唯一标识这本书,但没有指定哪里定位这本书。互联网中,URN使用非常少,几乎所有的URI都是URL。通常网页连接可称为URL,也可称为URI。习惯叫URL。

(二) 超文本
  超文本(hypertext),平时看到的网页是超文本解析而成。网页源代码是一系列HTML代码。

(三) HTTP和HTTPS
  URL开头的协议类型:http, https, ftp, sftp, smb等。

  HTTP的全称是Hyper Text Transfer Protocol,超文本传输协议。HTTP协议用于从网络传输超文本数据到本地浏览器的传送协议,它保证高效而准确地传送超文本文档。HTTP由万维网协会(World Wide Web Consortium )和Internet工作小组IETF (Internet Engineering Task Force)共同合作制定的规范,目前广泛使用的是HTTP 1.1 版本。

  HTTPS的全称是Hyper Text Transfer Protocol over Secure Socket Layer ,是以安全为目标的HTTP通道,是HTTP的安全版,即HTTP下加入SSL层,简称为HTTPS。

  HTTPS安全基础是SSL,通过它传输的内容都是经过SSL加密的,它的主要作用可以分两种:
  建立一个信息安全通道来保证数据传输的安全。
  确认网站的真实性,凡是使用了HTTPS的网站,都可以通过点击浏览器地址栏的锁头标志来查看网站认证之后的真实信息,也可以通过CA机构颁发的安全签章来查询。

  某个网站的CA证书不被CA机构信任,使用https的网站仍然会提示不安全。但实际上它的数据是加密传输的。比如:12306网站

(四) HTTP请求过程
  打开Chrome浏览器,进入“检查”-“Network",此时打开百度网站,在Network下方出现的一个个的条目,其中一个条目就代表一次发送请求和接收响应过程。其中各列的含义是:
  第一列:Name,请求名称,通常是URL的最后一部分内容当作名称
  第二列:Status,状态码,200表示响应成功。通过状态码判断发出请求后是否得到了正常的响应。
  第三列:Type,请求文档类型。document表示请求的是一个HTML文档,内容是HTML代码。
  第四列:Initiator,请求源,标记请求是由哪个对象或进程发起的。
  第五列:Size,从服务器下载的文件和请求的资源大小。缓存中的资源,显示的是 from cache
  第六列:Time,从发起请求到获取响应所用的总时间
  第七列:Waterfall,网络请求的可视化瀑布流
  点击name列下面的第一个条目:www.baidu.com可看到详细信息:
在headers中:
  首先是General部分,RequestURL为请求的URL, Request Method为请求的方法,Status Code为响应状态码,Remote Address 为远程服务器的地址和端口,Referrer Policy为Referrer 判别策略。

(五) 请求
  请求,由客户端向服务端发出,可以分为4部分内容:请求方法(Request Method)、请求的网址(Request URL)、请求头(Request Headers)、请求体(Request Body)。

1、请求
  常见的请求方法有两种: GET和POST。
  在浏览器中直接输入URL并回车,这便发起了一个GET请求,请求的参数会直接包含到URL里。
  POST请求大多在表单提交时发起。数据通常以表单的形式传输,而不会体现在URL中。

GET和POST请求方法有如下区别。
  GET请求中的参数包含在URL里面,数据可以在URL中看到,而POST请求的URL不会包含这些数据,数据都是通过表单形式传输的,会包含在请求体中。
  GET请求提交的数据最多只有1024字节,而POST方式没有限制。
  POST请求多用于:输入用户名和密码登录时,上传大文件时的请求。

  除了GET和POST请求,还有:HEAD, PUT, DELETE, CONNECT, OPTIONS, TRACE
请求方法小结

URL:请求的网址,唯一确定我们想请求的资源。

2、请求头
  请求头,用来说明服务器要使用的附加信息,比较重要的信息有Cookie 、Referer、User-Agent等。
常用头信息有:
  Accept: 请求报头域,用于指定客户端可接受哪些类型的信息。
  Accept-Language:指定客户端可接受的语言类型。
  Accept-Encoding:指定客户端可接受的内容编码。
  Host:确定请求资源的主机IP和端口号,内容为请求URL的原始服务器或网关的位置。HTTP1.l版本,请求必须包含此内容。
  Cookie:复数形式Cookies,网站为了辨别用户进行会话跟踪而存储在用户本地的数据。它的主要功能是维持当前访问会话。例如,我们输入用户名和密码成功登录某个网站后,服务器会用会话保存登录状态信息,后面我们每次刷新或请求该站点的其他页面时,会发现都是登录状态,这就是Cookies 的功劳。Cookies 里有信息标识了我们所对应的服务器的会话,每次浏览器在请求该站点的页面时,都会在请求头中加上Cookies 并将其发送给服务器,服务器通过Cookies识别出是我们自己,并且查出当前状态是登录状态,所以返回结果就是登录之后才能看到的网页内容。
  Referer:用来标识这个请求是从哪个页面发过来的,服务器可以拿到这一信息并做相应的处理,如做来源统计、防盗链处理等。
  User-Agent:简称UA,特殊的字符串头,可以使服务器识别客户使用的操作系统及版本、浏览器及版本等信息。在做爬虫时加上此信息,可以伪装为浏览器;如果不加,很可能会被识别出为爬虫。
  Content-Type:也叫互联网媒体类型(Internet Media Type)或者MIME类型,在HTTP协议消息头中,它用来表示具体请求中的媒体类型信息。例如,text/html 代表HTML格式,image/gif代表GIF图片,application/json代表JSON类型,更多对应关系可以查看此对照表:http://tool.oschina.net/commons。

3、请求体
  请求体-般承载的内容是POST请求中的表单数据,而对于GET请求,请求体则为空。
  只有设置Content-Type 为application/x-www-form-urlencoded,才会以表单数据的形式提交。
  将Content-Type设置为application/json来提交JSON 数据,或者设置为multipart/form-data来上传文件

 

(六) 响应
  响应,由服务端返回给客户端,可以分为三部分:响应状态码(Response Status Code )、响应头(Response Headers)和响应体(Response Body)。

1、响应状态码
  常见状态码有:200代表服务器正常响应,404代表页面未找到,500代表服务器内部发生错误。

常见的错误代码及错误原因

image
image


2、响应头
  响应头包含服务器对请求的应答信息,如Content-Type、Server、Set-Cookie等。常用头信息有:
  Date: 标识响应产生的时间。
  Last-Modified:指定资源的最后修改时间。
  Content-Encoding:指定响应内容的编码。
  Server:包含服务器的信息,比如名称、版本号等。
  Content-Type:文档类型,指定返回的数据类型是什么,如text/html代表返回HTML文档,application/x-javaScript代表返回JavaScript文件,image/jpeg 则代表返回图片。
  Set-Cookie:设置Cookies。响应头中的Set-Cookie 告诉浏览器需要将此内容放在Cookies中,下次请求携带Cookies请求。
  Expires:指定响应的过期时间, 可以使代理服务器或浏览器将加载的内容更新到缓存中。如果再次访问时,就可以直接从缓存中加载,降低服务器负载,缩短加载时间。

3、响应体
  最重要的就是响应体的内容。响应的正文数据都在响应体中,比如请求网页时,它的响应体就是网页的HTML代码;请求一张图片时,它的响应体就是图片的二进制数据。我们做爬虫请求网页后,要解析的内容就是响应体,

  在浏览器开发者工具中点击Preview,就可以看到网页的源代码,也就是响应体的内容,它是解析的目标。在爬虫时,主要通过响应体得到网页的源代码、JSON数据等, 然后从中做相应内容的提取。

二、网页基础
(一) 网页的组成
  网页可以分为三大部分一一HTML, CSS 和JavaScript。把网页比作一个人,HTML相当于骨架,JavaScript相当于肌肉,css相当于皮肤,三者结合起来才能形成一个完善的网页。

1、HTML
  HTML是用来描述网页的一种语言,全称Hyper Text Markup Language,即超文本标记语言。网页包括文字、按钮、图片和视频等各种复杂的元素,其基础架构就是HTML。不同类型的文字通过不同类型的标签来表示,如图片用img标签表示,视频用video标签表示,段落用p标签表示,它们之间的布局又常通过布局标签div嵌套组合而戚,各种标签通过不同的排列和嵌套才形成了网页的框架。

  在浏览器的“检查”/“Elements”中看到的就是网页的源代码。这个就是HTML,可以看出整个网页就是由各种标签嵌套组成而成的。这些标签定义的节点元素相互嵌套和组合形成了复杂的层次关系,就形成了网页的架构。

2、CSS
  css,全称叫作Cascading Style Sheets,即层叠样式表。“层叠”是指当在HTML中引用了数个样式文件,并且样式发生冲突时,浏览器能依据层叠顺序处理。“样式”指网页中文字大小、颜色、元素间距、排列等格式。

  css是目前唯一的网页页面排版样式标准,有了它的帮助,页面才会变得更为美观。

3、JavaScript
  JavaScript简称JS,是一种脚本语言。HTML和css配合使用,看到的是一种静态信息,缺乏交互性。在网页里可以看到一些交互和动画效果,如下载进度条、提示框、轮播图等,就是JavaScript做出来的。JavaScript实现了一种实时、动态、交互的页面功能。

(二) 网页的结构
(详细内容参考P89)

(三) 节点树及节点间的关系
  在HTML中,所有标签定义的内容都是节点,它们构成了一个HTML DOM树。
  DOM是W3C(万维网联盟)的标准,其英文全称Document Object Model,即文档对象模型。它定义了访问HTML和XML文档的标准:
  W3C文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。
  W3CDOM 标准被分为3 个不同的部分。
  核心DOM:针对任何结构化文档的标准模型。
  XML DOM:针对XML文挡的标准模型。
  HTML DOM:针对HTML文档的标准模型。

根据W3C的HTML DOM标准,HTML文档中的所有内容都是节点。
整个文档是一个文档节点。
每个HTML元素是元素节点。
HTML元素内的文本是文本节点。
每个HTML属性是属性节点。
注释是注释节点。

HTML DOM将HTML文档视作树结构,这种结构被称为节点树。
通过HTML DOM,树中的所有节点均可通过JavaScript访问,所有HTML节点元素均可被修改,也可以被创建或删除。

  节点树中的节点彼此拥有层级关系。常用父(parent)、子(child)和兄弟(sibling)等术语描述这些关系。父节点拥有子节点,同级的子节点被称为兄弟节点。
  在节点树中,顶端节点称为根(root)。除了根节点之外,每个节点都有父节点,同时可拥有任意数量的子节点或兄弟节点。

(四) 选择器
  在css中,使用css选择器来定位节点。例如,div节点中的id为container ,可以表示为#container ,其中#开头代表选择id,其后紧跟id的名称。另外,要选择class为wrapper 的节点,可使用.wrapper,这里以点(.)开头代表选择class,其后紧跟class的名称。另外,还可以根据标签名筛选,例如想选择二级标题,直接用h2即可。这是最常用的3种表示,分别是根据id、class 、标签名筛选,要牢记它们的写法。
  css选择器还支持嵌套选择,各个选择器之间加上空格分隔开便可以代表嵌套关系,如#container .wrapper p 则代表先选择id为container的节点,然后选中其内部的class为wrapper的节点,然后再进一步选中其内部的p节点。
  另外,如果不加空格,则代表并列关系,如div#container .wrapperp .text代表先选择id为container的div节点,然后选中其内部的class为wrapper的节点,再进一步选中其内部的class为text的p节点。这就是css选择器,其筛选功能非常强大。

css选择器的其他语法规则如下面所示

image
image

另外一个较常用的选择器是XPath。

三、爬虫的基本原理
  互联网看作一张大网,爬虫便是在网上爬行的蜘蛛。网的节点可比作一个个网页,爬虫到这些网页就是访问该网页,获取其信息。节点间的连线可比作网页与网页之间的链接关系。在爬完一个节点后可顺着节点连线继续爬行到下一个节点,即通过网页继续获取后续的网页,这样便可爬取到整个网的节点,网站数据也就被抓取下来。

(一) 爬虫概述
爬虫就是获取网页并提取和保存信息的自动化程序。

1、获取网页
  获取网页,是获取网页的源代码。源代码包含了网页的部分有用信息,获取了源代码,可从中提取想要的信息。关键部分:构造一个请求发送给服务器,接收响应并将其解析出来。实现这个操作,可用urllib,requests库。请求和响应都可用类库提供的数据结构来表示,得到响应之后只需要解析数据结构中的Body部分即可,即得到网页的源代码,这样就可以用程序来实现获取网页的过程了。

2、提取信息
  分析源代码,提取想要的数据。常用方法是采用正则表达式,但在构造表达式时比较复杂且容易出错。
  由于网页结构是有规则的,网页节点属性、CSS选择器或XPath提取网页信息库,如 Beautiful Soup、pyquery、lxml等。这些库可以高效提取网页信息,如节点属性、文本值等。

3、保存数据
  可保存为TXT文本或JSON文本,也可保存到数据库,如Mysql和MongoDB。借助SFTP操作也可保存到远程服务器。

4、自动化操作
  让爬虫任务自动完成,可进行异常处理、错误重试等操作,确保爬取持续高效地运行。

(二) 能抓怎样的数据
  常规网页,即HTML源代码。
  有些网页返回的是JSON字符串(API接口大多采用这样的形式),方便传输和解析。数据提取方便。还有二进制数据,如图片、视频和音频等。爬虫可以将这些二进制数据抓取下来保存成对应的文件名。还有各种扩展名文件,如CSS、JavaScript和配置文件等,只要浏览器可以访问到,就可以抓取下来。上面这些都有各自对应的URL,可能是HTTP或HTTPS协议。这种数据是可以抓取的。

(三) JavaScript渲染页面
  有很多网页采用Ajax、前端模块化工具来构建,整个网页是JavaScript渲染出来的,此时原始的HTML代码是一个空壳。在这种HTML代码中,body节点会有指向JavaScript文件的属性。当请求到的源代码与浏览器中的页面源代码不一样,可分析其后台的Ajax接口,可使用Selenium、Splash库为实现模拟JavaScript渲染。

四、会话和Cookies
  打开网页提示登录、打开网站自动登录,有些登录过段时间失效,有些登录长久不失效。这些涉及到会话(Session)和Cookies的相关内容。

(一) 静态网页和动态网页
  静态网页:加载速度快,编写简单,但可维护性差,不能根据URL灵活多变的显示内容。
  动态网页:可动态解析URL中的参数变化,关联数据库并动态呈现不同的页面内容,灵活多变。现在多数网站都是动态网站,不在是一个简单的HTML,而是由JSP,PHP,Python等语言编写,功能强大的网页。
  动态网页可以实现用户注册、登录功能。某些网站登录后,可以长时间保持登录状态。这是会话和Cookies共同产生的结果。

(二) 无状态HTTP
  HTTP的无状态是指HTTP协议对事务处理是没有记忆能力的,服务器不知道客户端是什么状态。当向服务器发送请求后,服务器解析此请求,然后返回对应的响应,服务器负责完成这个过程,这个过程是完全独立的,服务器不会记录前后状态的变化,也就是缺少状态记录。还要处理前面的信息,则必须重传,这导致额外传递一些前面的重复请求,才能获取后续响应。
  两个用于保持HTTP连接状态的技术,分别是会话(Session)和Cookies。会话在服务端,就是网站的服务器,用来保存用户的会话信息;Cookies在客户端,可以理解为浏览器端,有了Cookies,浏览器在下次访问网页时会自动附带上它发送给服务器,服务器通过识别Cookjes并鉴定出是哪个用户,然后再判断用户是否是登录状态,然后返回对应的响应。
  可以认为Cookies里面保存了登录的凭证,有了它,在下次请求携带Cookies发送请求而不必重新输入用户名、密码等信息重新登录了。
  在爬虫时,需要登录的页面时,直接登录成功后获取的Cookies放在请求头里面直接请求,而不必重新登录。

1、会话(Session)
  会话是指有始有终的一系列动作/消息。
  而在Web中,会话对象用来存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在会话对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的Web页时如果该用户还没有会话,则Web服务器将自动创建一个会话对象。当会话过期或被放弃后,服务器将终止该会话。

2、Cookies
  Cookies 指某些网站为了辨别用户身份、进行会话跟踪而存储在用户本地终端上的数据。
a.会话维持
  当客户端第一次请求服务器时,服务器会返回一个请求头中带有Set-Cookie字段的响应给客户端,用来标记是哪一个用户,客户端浏览器会把Cookies保存起来。当浏览器下一次再请求该网站时,浏览器会把此Cookies放到请求头一起提交给服务器,Cookies携带了会话ID信息,服务器检查该Cookies即可找到对应的会话是什么,然后再判断会话来以此来辨认用户状态。
  Cookies和会话需要配合,一个处于客户端,一个处于服务端,二者共同协作,就实现了登录会话控制。
b.属性结构
  查看Cookies属性结构,在浏览器开发工具中的Application选项卡,左侧有一具Storage部分的最后一项为Cookies。打开看到的就是Cookies信息。该信息的字段分别有:
  Name:Cookie的名称。一旦创建,便不可更改。
  Value:该Cookie的值。如果值为Unicode字符,需要为字符编码。为二进制数据,需使用BASE64编码。
  Domain:可以访问该Cookie的域名。
  MaxAge:该Cookie失效的时间,单位为秒,常和Expires一起使用,通过它可以计算其有效时间。MaxAge为正数,则该Cookie在MaxAge秒之后失效。如果为负数则关闭浏览器时Cookie即失效,浏览器也不会以任何形式保存该Cookie 。
Path:该Cookie的使用路径。如果设置为/path/ ,则只有路径为/path/的页面可以访问该Cookie 。如果设置为/,则本域名下的所有页面都可以访问该Cookie 。
  Size字段:此Cookie 的大小。
  HTTP字段:Cookie的httponly属性。若此属性为true,则只有在HTTP头中会带有此Cookie的信息,而不能通过document.cookie来访问此Cookie。
  Secure:该Cookie是否仅被使用安全协议传输。安全协议有HTTPS和SSL等,在网络上传输数据之前先将数据加密。默认为false 。
c.会话Cookie 和持久Cookie
  会话Cookie是把Cookie放在浏览器内存里,浏览器关闭后该Cookie即失效;持久Cookie保存到客户端的硬盘中,下次可以继续使用,用于长久保持用户登录状态。
  严格来说,没有会话Cookie和持久Cookie之分,只是由Cookie的MaxAge或Expires字段决定了过期的时间。
持久化登录的网站其实是把Cookie的有效时间和会话有效期设置得比较长,下次再访问页面时仍然携带之前的Cookie ,就可以直接保持登录状态。

(三) 常见误区
  关闭浏览器时,浏览器不会主动在关闭之前通知服务器它将要关闭,所以服务器根本不会有机会知道浏览器已经关闭。有这种错觉,是因为会话机制使用会话Cookie来保存会话ID信息,而关闭浏览器后Cookies就消失了,再次连接服务器时,也就无法找到原来的会话了。如果服务器设置的Cookies保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的Cookies发送给服务器,则再次打开浏览器,仍然能够找到原来的会话ID,依旧还是可以保持登录状态的。
  由于关闭浏览器不会导致会话被删除,这就需要服务器为会话设置一个失效时间,当距离客户端上一次使用会话的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把会话删除以节省存储空间。
会话百度百科:https://baike.baidu.com/item/session/479100
Cookies百度百科:https://baike.baidu.com/item/cookie/1119
HTTPCookie维基百科:https://en.wikipedia.org/wiki/HTTP_cookie
会话和几种状态保持方案理解:http://www.mamicode.com/info-detail-46545.html

五 代理的基本原理
  在频繁访问某些网站时,会提示访问频率太高,出现403 Forbidden的情况。说明这个网站采取了一些反爬虫措施。此时需要借助代理以某种方式伪装IP,让服务器识别不出是由本机发起的请求,从而达到达到防止封IP的作用。

(一) 基本原理
  代理指的是代理服务器,英文叫作proxy server,它的功能是代理网络用户去取得网络信息。它是网络信息的中转站。在本机设置了代理服务器,实际上是在本机和服务器之间搭建一个桥,此时本机向代理服务器发送请求,由代理服务器向Web服务器发起请求。接着由代理服务器再把Web服务器返回的响应转发给本机。这样就正常访问网页。在这个过程中,Web服务器识别出的真实IP就不再是本机的IP,这就成功实现了IP伪装,这也是代理的基本原理。

(二) 代理的作用
  突破自身IP访问限制,访问一些平时不能访问的站点。
  访问一些单位或团体内部资源:比如使用教育网内地址段免费代理服务器,就可以用于对教育网开放的各类FTP下载上传,以及各类资料查询共享等服务。
  提高访问速度:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度。
  隐藏真实IP:上网者也可以通过这种方法隐藏向己的IP,免受攻击。对于爬虫来说,用代理就是为了隐藏自身IP,防止自身的IP被封锁。

(三) 爬虫代理
  频繁访问网站,会被要求输入验证码或被封锁IP,这会给爬虫带来极大不便。使用代理隐藏真实IP,让服务器误以为是代理服务器在请求自己。在爬取过程不断更换代理,就不会被封锁,以达到好的爬取效果。

(四) 代理分类
可根据协议区分,也可根据其匿名程度区分。

1、根据协议区分
根据代理的协议,代理可以分为如下类别。
  FTP代理服务器:主要用于访问FTP服务器,一般有上传、下载以及缓存功能,端口一般为21 、2121等。
  HTTP代理服务器:主要用于访问网页,一般有内容过滤和缓存功能,端口一般为80、8080、3128等。
  SSL/TLS代理:主要用于访问加密网站,一般有SSL或TLS加密功能(最高支持128位加密强度),端口一般为443。
  RTSP代理:主要用于访问Real流媒体服务器,一般有缓存功能,端口一般为554。
  Telnet代理:主要用于telnet远程控制(黑客入侵计算机时常用于隐藏身份),端口一般为23。
  POP3/SMTP代理:主要用于POP3/SMTP方式收发邮件,一般有缓存功能,端口一般为110/25。
  SOCKS代理:只是单纯传递数据包,不关心具体协议和用法,所以速度快很多,一般有缓存功能,端口一般为1080。
  SOCKS代理协议又分为SOCKS4和SOCKS5,前者只支持TCP,而后者支持TCP和UDP,还支持各种身份验证机制、服务器端域名解析等。简单来说,SOCKS4 能做到的SOCKS5都可以做到,但SOCKS5能做到的SOCKS4不一定能做到。

2、根据匿名程度区分
  高度匿名代理:会将数据包原封不动地转发,在服务端看来就好像真的是一个普通客户端在访问,而记录的IP是代理服务器的IP。
  普通匿名代理:会在数据包上做一些改动,服务端上有可能发现这是个代理服务器,也有一定几率追查到客户端的真实IP。代理服务器通常会加入的HTTP头有HTTP_VIA 和HTTP_X_FORWARDED_FOR。
  透明代理:不但改动了数据包还会告诉服务器客户端的真实IP。这种代理除了能用缓存技术提高浏览速度,能用内容过滤提高安全性之外,并无其他显著作用,最常见的例子是内网中的硬件防火墙。
  间谍代理:指组织或个人创建的用于记录用户传输的数据,然后进行研究、监控等目的的代理服务器。

(五) 常见代理设置
  使用网上的免费代理:最好使用高匿代理,另外可用的代理不多,需要在使用前筛选一下可用代理,也可以进一步维护一个代理池。
  使用付费代理服务:互联网上存在许多代理商,可以付费使用,质量比免费代理好很多。
  ADSL拨号:拨一次号换一次IP,稳定性高,也是一种比较有效的解决方案。

代理服务器维基百科:https://zh.wikipedia.org/wiki/代理服务器
代理百度百科:https://baike.baidu.com/item/代理/3242667

posted @ 2019-01-23 10:59  远方那一抹云  阅读(537)  评论(0编辑  收藏  举报