1

Python爬虫编程实现(1):HTTP基础

 2 years ago
source link: https://blog.csdn.net/nokiaguy/article/details/118570963
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

        由于网络爬虫要处理的主要目标是网页,所以在编写爬虫之前,非常有必要了解一些爬虫的基础知识,例如HTTP、HTML、CSS、Session、Cookie等。在本专栏开始的几篇文章中会先讲解这些基础知识。

1. URI和URL

        通过浏览器访问网页,首先就要接触到URL(Uniform Resource Location,统一资源定位符),不过在很多场景,经常会遇到URI,那么URI是什么呢?Uri的英文全称是Uniform Resource Identifier,中文的意思是“统一资源标识符”。

        在很多时候,URL与URI可以互换,例如,https://geekori.com/edu/course.php?c_id=6是geekori.com上一个页面的链接,这是一个URL,同时也是一个URI。也就是说,在geekori.com上有一个页面,通过URL/URI指定了该页面的访问协议(https)、访问域名(geekori.com)、访问路径(/edu/course.php)和参数(?c_id=6)。通过这样一个链接,我们可以在互联网上唯一定位这个资源,这就是URL/URI。

        既然同时存在URL和URI,那么它们肯定有区别。其实URL是URI的子集,也就是说,每个URL都是URI,但并不是所有的URI都是URL。那么有哪些URI不是URL呢?URI除了包含URL外,还有URN(Universal Resource Name,统一资源名称)。URN只命名资源而不指定如何获得资源,例如,P2P下载中使用的磁力链接是URN的一种实现,它可以持久化的标识一个BT资源,资源分布式的存储在P2P网络中,无需中心服务器用户即可找到并下载它。在磁力链接中类似 magnet:?xt=urn:btih:开头的字符串就是一个URN。而URL不仅命名了资源,还指定了如何获取资源,如获取资源的协议、域名、路径等。不过对于爬虫来说,主要使用URL,URN用的并不多。用于访问网页的链接可以称为URL,也可以称为URI,我个人习惯称为URL。

2. 超文本

                超文本,英文名字是hypertext。在Web应用中,超文本主要是指HTML代码。我们在浏览器中看到的内容就是浏览器解析超文本(HTML代码)后的输出结果。这些HTML代码由若干个节点组成,例如,用于显示图像的img节点,用于换行的p节点,用于显示表格的table节点。浏览器解析这些节点后,就形成了我们平常看到的页面,而页面的源代码(HTML代码)就可以称为超文本。

任何浏览器都可以查看当前页面的源代码,本节以Chrome为例,在Chrome中打开任意一个页面,如京东商城,在页面的右键菜单中单击“检查”菜单项,就会打开浏览器的开发者工具,在Elements节点页可以看到当前页面的源代码,如图1所示。

3. HTTP与HTTPS

        任何一个URL的开头都指明了协议,例如,在访问京东商城https://www.jd.com时,协议是https,Web资源除了https,还有http。除了以这两个协议开头的URL,还有以ftp、sftp、smb等协议开头的URL。那么协议是指什么呢?其实这里的协议就是指数据传输协议,也就是数据的传输格式(数据传输规范)。只要客户端(浏览器)和服务端都遵循这些规范,就可以正常传输数据。由于爬虫主要涉及到的协议是HTTP和HTTPS,所以本节主要会介绍这两种协议。

        HTTP的全称是Hyper Text Transfer Protocol,中文名是“超文本传输协议”。HTTP理论上可以传输任何类型的数据,包括超文本数据、普通的文本数据、二进制数据(如图像、视频文件等),不过对于爬虫来说,主要关注通过HTTP传输的超文本数据。HTTP由万维网协会(World Wide Web Consortium,W3C)和Internet工作小组(Internet Engineering Task Force,IETF)共同合作制定的规范,目前广泛使用的是HTTP 1.1。

        HTTPS的全称是Hyper Text Transfer Protocol over Secure Socket Layer,是安全的HTTP数据通道,也可以认为是HTTP的安全版本,即HTTP下加入SSL层,简称为HTTPS。通过HTTPS传输的数据都是加密的,而通过HTTP传输的数据都是明文的。

        HTTPS的安全基础是SSL,因此通过HTTPS传输的数据都是经过SSL加密的,主要有如下两种作用。

  • 建立一个信息安全通道来保证数据传输的安全。
  • 确认网站是安全和真实的。

        第1个作用非常好理解,那么第2个作用是什么意思呢?还是以京东商城为例,在chrome浏览器中显示京东商城首页后,在浏览器地址栏左侧会出现一个小锁,单击小锁,会显示如图2所示的弹出页面。最上方会显示“连接是安全的”。这就表明对京东商城访问是安全的。

        为了更进一步证明我们访问的确实是京东商城,单击图2-2所示弹出页面的“证书(有效)”连接,会显示证书的颁发机构,单击“细节”会显示更多关于证书的信息,如图3所示。

        从证书信息可以看出,京东商城使用了GlobalSign签发的证书,而该证书正是颁发给北京的京东公司,顶级域名是jd.com,也就是说,www.jd.com、wt.jd.com这些域名都会使用这个证书,这就证明了我们访问的https://www.jd.com不仅是安全的,而且的确是京东商城的官方网站。

        现在越来越多的网站和App都已经向HTTPS方向发展,例如:

  • 苹果公司强制所有的iOS App在2017年1月1日前全部改为使用HTTPS加密,否则App就无法在应用商店上架。
  • 从Chrome 56(Google在2017年1月推出)开始,对未进行HTTPS加密的网站链接显示风险提示,也就是在地址栏左侧显示一个感叹号图标,并且显示“不安全”字样。单击感叹号图标,在弹出页面会显示“您与此网站之间建立的连接不安全”,如图4所示。
  • 微信小程序要求必须使用HTTPS请求与服务端通信。

        显示这个信息的原因是尽管网站使用了SSL进行加密,但使用的证书是自己或其他未被当前浏览器承认的第三方签发的(查看图5所示网站的证书,会显示如图6所示的内容,很明显,这是自签发的证书),相当于在出庭去作证,而法庭首先需要确认证人本身是可靠的。这里法庭就相当于浏览器,证人相当于证书。如果是自己或其他未被法庭承认的证人去作证,当然是无效证词了,就像不能自己证明自己无罪一样。尽管这类网站通过单击“高级”按钮,然后按提示操作仍然可以继续访问网站,但并不建议这样做,至少浏览器是这么建议的。不过这类网站在传输数据时仍然是加密的,只是在浏览器上会提示不安全。对于一些应用,可以利用自签名的HTTPS网站传输加密数据,不过对于一些应用,如Android App,是要求签名必须被当前系统认可的才可以访问,因此,如果要自己搭建基于HTTPS的网站,最好到相关权威机构购买证书。

4. HTTP的请求过程

        在浏览器地址栏中输入一个URL,按Enter键会在浏览器中显示页面内容。实际上,这个过程是按Enter键后,浏览器根据URL指定的地址向服务端发送一个请求,当服务端接收到这个请求后,会对请求数据进行解析,并处理解析后的数据,然后返回对应的响应数据,这些响应数据最终会被回传给浏览器。对于浏览器来说,这些响应数据的核心内容就是页面的源代码(主要是HTML代码),浏览器会对这些源代码进行解析,然后将解析结果展示在浏览器上,这就是我们最终看到的页面,整个过程如图7所示。

         这里的客户端表示PC、手机以及任何计算设备的浏览器,服务器表示网站所在的服务器。为了更直观说明这个过程,可以在Chrome浏览器的开发者工具中的Network监听组件观察Web页面请求服务器的各类Url。

        打开Chrome浏览器,进入京东商城首页,在页面右键菜单中单击“检查”菜单项打开开发者工具,然后切换到Network面板,就会看到该页面中会出现很多Url,如图8所示。

在Network面板中的每一个条目表示一个Url,每列的含义如下:

  • Name:请求的文件名。通常来讲,一个Url就是请求服务器的一个文件,而Name列的值就是这个Url最后的文件名。例如,请求Url是https://m.360buyimg.com/babel/jfs/abc.jpg,那么Name列的值就是abc.jpg。
  • Status:响应状态码。如果服务器成功响应客户端,通常是200。通过响应状态码,我们可以判断发送的请求你是否得到了服务器的正常响应。
  • Type:请求的文档类型。一般会根据响应头的content-type字段确定文档类型,例如,请求的Url是https://m.360buyimg.com/babel/jfs/abc.jpg,content-type字段的值就是image/jpeg,所以Type列的值就是jpeg。
  • Initiator:请求源。用来标记请求是由哪个程序发起的。
  • Size:由于向服务器发送请求后,服务器会返回对应的资源,这个Size列就是返回资源的大小。如果资源从本地缓存中获取,那么Size列的值是from disk cache。
  • Time:从发起请求到获取响应所用的总时间。
  • Waterfall:网络请求的可视化瀑布流。

单击某个条目,可以看到更详细的信息,如图9所示。

在详细信息页面有3个部分:General、Response Headers和Request Headers,分表表示基本信息、响应头信息和请求头信息。其中General部分的字段含义如下:

  • Request URL:请求的完整URL。
  • Request Method:请求的方法,本例是GET,另外一个常用的方法是POST。
  • Status Code:响应状态码。
  • Remote Address:远程服务器的地址和端口号。
  • Referrer Policy:Referrer判别策略。

在客户端和服务器交互的过程中,涉及到两个“头”,一个是请求头(Request Headers),一个是响应头(Response Headers)。请求头和响应头都由若干字段组成,用于描述在请求和响应过程中相关信息。例如,请求信息由什么客户端发出的,会通过请求头的User-Agent字段描述,通过该字段,服务器就会知道客户端是通过Chrome、还是Firefox,或是IE发出的请求。而浏览器可以通过响应头的content-type字段得到服务器返回资源的类型。在下一篇文章中会详细介绍请求头和响应头包含哪些内容。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK