python爬虫入门教程--快速理解HTTP协议(一)


Posted in Python onMay 25, 2017

前言

爬虫的基本原理是模拟浏览器进行 HTTP 请求,理解 HTTP 协议是写爬虫的必备基础,招聘网站的爬虫岗位也赫然写着熟练掌握HTTP协议规范,写爬虫还不得不先从HTTP协议开始讲起

HTTP协议是什么?

你浏览的每一个网页都是基于 HTTP 协议呈现的,HTTP 协议是互联网应用中,客户端(浏览器)与服务器之间进行数据通信的一种协议。协议中规定了客户端应该按照什么格式给服务器发送请求,同时也约定了服务端返回的响应结果应该是什么格式。

只要大家都按照协议规定方式发起请求和返回响应结果,任何人都可以基于HTTP协议实现自己的Web客户端(浏览器、爬虫)和Web服务器(Nginx、Apache等)。

HTTP 协议本身是非常简单的。它规定,只能由客户端主动发起请求,服务器接收请求处理后返回响应结果,同时 HTTP 是一种无状态的协议,协议本身不记录客户端的历史请求记录。

python爬虫入门教程--快速理解HTTP协议(一)

HTTP 协议是如何规定请求格式和响应格式的呢?换言之,客户端按照什么格式才能正确发起 HTTP 请求呢?服务端按照什么格式返回响应结果客户端才能正确解析?

HTTP 请求

HTTP 请求由3部分组成,分别是请求行、请求首部、请求体,首部和请求体是可选的,并不是每个请求都需要的。

python爬虫入门教程--快速理解HTTP协议(一)

请求行

请求行是每个请求必不可少的部分,它由3部分组成,分别是请求方法(method)、请求URL(URI)、HTTP协议版本,以空格隔开。

HTTP协议中最常用的请求方法有:GET、POST、PUT、DELETE。GET 方法用于从服务器获取资源,90%的爬虫都是基于GET请求抓取数据。

请求 URL 是指资源所在服务器的路径地址,比如上图的例子表示客户端想获取 index.html 这个资源,它的路径在服务器 foofish.net 的根目录(/)下面。

请求首部

因为请求行所携带的信息量非常有限,以至于客户端还有很多想向服务器要说的事情不得不放在请求首部(Header),请求首部用于给服务器提供一些额外的信息,比如 User-Agent 用来表明客户端的身份,让服务器知道你是来自浏览器的请求还是爬虫,是来自 Chrome 浏览器还是 FireFox。HTTP/1.1 规定了47种首部字段类型。HTTP首部字段的格式很像 Python 中的字典类型,由键值对组成,中间用冒号隔开。比如:

User-Agent: Mozilla/5.0

因为客户端发送请求时,发送的数据(报文)是由字符串构成的,为了区分请求首部的结尾和请求体的开始,用一个空行来表示,遇到空行时,就表示这是首部的结尾,请求体的开始。

请求体

请求体是客户端提交给服务器的真正内容,比如用户登录时的需要用的用户名和密码,比如文件上传的数据,比如注册用户信息时提交的表单信息。

现在我们用 Python 提供的最原始API socket 模块来模拟向服务器发起一个 HTTP 请求

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
 # 1. 与服务器建立连接
 s.connect(("www.seriot.ch", 80))
 # 2. 构建请求行,请求资源是 index.php
 request_line = b"GET /index.php HTTP/1.1"
 # 3. 构建请求首部,指定主机名
 headers = b"Host: seriot.ch"
 # 4. 用空行标记请求首部的结束位置
 blank_line = b"\r\n"

 # 请求行、首部、空行这3部分内容用换行符分隔,组成一个请求报文字符串
 # 发送给服务器
 message = b"\r\n".join([request_line, headers, blank_line])
 s.send(message)

 # 服务器返回的响应内容稍后进行分析
 response = s.recv(1024)
 print(response)

HTTP 响应

服务端接收请求并处理后,返回响应内容给客户端,同样地,响应内容也必须遵循固定的格式浏览器才能正确解析。HTTP 响应也由3部分组成,分别是:响应行、响应首部、响应体,与 HTTP 的请求格式是相对应的。

python爬虫入门教程--快速理解HTTP协议(一)

响应行

响应行同样也是3部分组成,由服务端支持的 HTTP 协议版本号、状态码、以及对状态码的简短原因描述组成。

状态码是响应行中很重要的一个字段。通过状态码,客户端可以知道服务器是否正常处理的请求。如果状态码是200,说明客户端的请求处理成功,如果是500,说明服务器处理请求的时候出现了异常。404 表示请求的资源在服务器找不到。除此之外,HTTP 协议还很定义了很多其他的状态码,不过它不是本文的讨论范围。

响应首部

响应首部和请求首部类似,用于对响应内容的补充,在首部里面可以告知客户端响应体的数据类型是什么?响应内容返回的时间是什么时候,响应体是否压缩了,响应体最后一次修改的时间。

响应体

响应体(body)是服务器返回的真正内容,它可以是一个HTML页面,或者是一张图片、一段视频等等。

我们继续沿用前面那个例子来看看服务器返回的响应结果是什么?因为我只接收了前1024个字节,所以有一部分响应内容是看不到的。

b'HTTP/1.1 200 OK\r\n
Date: Tue, 04 Apr 2017 16:22:35 GMT\r\n
Server: Apache\r\n
Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n
Set-Cookie: PHPSESSID=66bea0a1f7cb572584745f9ce6984b7e; path=/\r\n
Transfer-Encoding: chunked\r\n
Content-Type: text/html; charset=UTF-8\r\n\r\n118d\r\n

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n\n
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n
<head>\n\t
 <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1" /> \n\t
 <meta http-equiv="content-language" content="en" />\n\t
...
</html>

从结果来看,它与协议中规范的格式是一样的,第一行是响应行,状态码是200,表明请求成功。第二部分是响应首部信息,由多个首部组成,有服务器返回响应的时间,Cookie信息等等。第三部分就是真正的响应体 HTML 文本。

至此,你应该对 HTTP 协议有一个总体的认识了,爬虫的行为本质上就是模拟浏览器发送HTTP请求,所以要想在爬虫领域深耕细作,理解 HTTP 协议是必须的。

总结

以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python3基础之list列表实例解析
Aug 13 Python
用Python的Django框架完成视频处理任务的教程
Apr 02 Python
Django框架下在URLconf中指定视图缓存的方法
Jul 23 Python
深入理解python try异常处理机制
Jun 01 Python
利用Python读取文件的四种不同方法比对
May 18 Python
浅析Git版本控制器使用
Dec 10 Python
深入理解Python 关于supper 的 用法和原理
Feb 28 Python
python ddt实现数据驱动
Mar 14 Python
Python3.6笔记之将程序运行结果输出到文件的方法
Apr 22 Python
python 利用for循环 保存多个图像或者文件的实例
Nov 09 Python
django为Form生成的label标签添加class方式
May 20 Python
一文搞懂python异常处理、模块与包
Jun 26 Python
用生成器来改写直接返回列表的函数方法
May 25 #Python
Python随机读取文件实现实例
May 25 #Python
利用Anaconda完美解决Python 2与python 3的共存问题
May 25 #Python
Python实现的简单dns查询功能示例
May 24 #Python
Python向日志输出中添加上下文信息
May 24 #Python
Python常见加密模块用法分析【MD5,sha,crypt模块】
May 24 #Python
Python简单生成8位随机密码的方法
May 24 #Python
You might like
PHP+SQL 注入攻击的技术实现以及预防办法
2010/12/29 PHP
PHP设置一边执行一边输出结果的代码
2013/09/30 PHP
Laravel模板引擎Blade中section的一些标签的区别介绍
2015/02/10 PHP
Yii2.0多文件上传实例说明
2017/07/24 PHP
Laravel如何同时连接多个数据库详解
2019/08/13 PHP
ASP.NET jQuery 实例16 通过控件CustomValidator验证RadioButtonList
2012/02/03 Javascript
基于jQuery的公告无限循环滚动实现代码
2012/05/11 Javascript
javascript 二进制运算技巧解析
2012/11/27 Javascript
Javascript中arguments和arguments.callee的区别浅析
2015/04/24 Javascript
jquery.fastLiveFilter.js实现输入自动过滤的方法
2015/08/11 Javascript
牛叉的Jquery——Jquery与DOM对象的互相转换及DOM的三种操作
2015/10/29 Javascript
jquery利用拖拽方式在图片上添加热链接
2015/11/24 Javascript
Javascript之BOM(window对象)详解
2016/05/25 Javascript
Js利用console计算代码运行时间的方法示例
2017/09/24 Javascript
vuejs 切换导航条高亮(路由菜单高亮)的方法示例
2018/05/29 Javascript
js实现磁性吸附的示例
2020/10/26 Javascript
[47:52]完美世界DOTA2联赛PWL S2 PXG vs InkIce 第二场 11.26
2020/11/30 DOTA
[原创]pip和pygal的安装实例教程
2017/12/07 Python
Python使用flask框架操作sqlite3的两种方式
2018/01/31 Python
用pycharm开发django项目示例代码
2018/10/24 Python
python进阶之多线程对同一个全局变量的处理方法
2018/11/09 Python
使用python绘制二元函数图像的实例
2019/02/12 Python
解析python 类方法、对象方法、静态方法
2020/08/15 Python
python 爬取腾讯视频评论的实现步骤
2021/02/18 Python
css3的transition效果和transfor效果示例介绍
2013/10/30 HTML / CSS
HTML 5 input placeholder 属性如何完美兼任ie
2014/05/12 HTML / CSS
HTML5手机端弹出遮罩菜单特效代码
2016/01/27 HTML / CSS
德国团购网站:Groupon德国
2018/03/13 全球购物
加拿大时装零售商:Influence U
2018/12/22 全球购物
英国最大的独立玩具专卖店:The Entertainer
2019/09/06 全球购物
城市精细化管理实施方案
2014/03/04 职场文书
幼儿园小班见习报告
2014/10/31 职场文书
公务员年度个人总结
2015/02/12 职场文书
2015年小学辅导员工作总结
2015/05/27 职场文书
用python自动生成日历
2021/04/24 Python
5人制售《绝地求生》游戏外挂获利500多万元 被判刑
2022/03/31 其他游戏