Python 仅获取响应头, 不获取实体的实例


Posted in Python onAugust 21, 2019

Python Just get Response Headers, not get content.

1. Use HEAD method

>>> import requests
>>> res = requests.head("http://www.baidu.com/")
>>> req.head("https://www.baidu.com/").headers
{'Content-Encoding': 'gzip', 'Server': 'bfe/1.0.8.18', 'Last-Modified': 'Mon, 13 Jun 2016 02:50:08 GMT', 'Connection': 'Keep-Alive', 'Pragma': 'no-cache', 'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Date': 'Fri, 13 Oct 2017 04:36:20 GMT', 'Content-Type': 'text/html'}
>>> res.ok
True
>>> res.content
''
# 但是会遇到一些问题, 比如, 服务器不支持 HEAD, 或者拒绝 HEAD.
# 如下情况就被拒绝
#
>>> res = req.head("https://www.douban.com/subject/1/")
>>> res
<Response [403]>
>>> res.ok
False
>>> res.content
''
>>> res.headers
{'Content-Encoding': 'gzip', 'Keep-Alive': 'timeout=30', 'Server': 'dae', 'Connection': 'keep-alive', 'Date': 'Fri, 13 Oct 2017 04:39:00 GMT', 'Content-Type': 'text/html'}

不是很通用, 因为有些服务器不支持.

2. Use urllib

import urllib
>>> res = urllib.urlopen("http://127.0.0.1:8000/git.exe")
>>> res.url
'http://127.0.0.1:8000/git.exe'
>>> res.headers.headers
['Server: SimpleHTTP/0.6 Python/2.7.10\r\n', 'Date: Fri, 13 Oct 2017 06:06:37 GMT\r\n', 'Content-type: application/x-msdownload\r\n', 'Content-Length: 7569408\r\n', 'Last-Modified: Fri, 16 Dec 2016 07:09:32 GMT\r\n']
>>> len(r.read())
7569408
# urllib 只有在调用 read/readline/readlines 的时候才会从 web 服务器读取数据.
# 源码可以在 urllib/httplib 中找到. 
# urllib.py
def urlopen(url, ...):
 opener = FancyURLopener()
 return opener.open(url)
class FancyURLopener(URLopener).open():
 getattr(self, name)(url)
class URLopener.open_http():
 errcode, errmsg, headers = h.getreply()
 if(200 <= errcode < 300):
  return addinfourl(fp, headers, "http:" + url, errcode)
 else:
  if data is None:
   return self.http_error(url, fp, errcode, errmsg, headers)
  else:
   return self.http_error(url, fp, errcode, errmsg, headers, data)
class URLopener.http_error():
 return method(url, fp, errcode, errmsg, headers)
class FancyURLopener.http_error_default():
 return addinfourl(fp, headers, "http:" + url, errcode)
class addinfourl(addbase):
 # 代码中并没有对 fp 做任何操作,包括读写. 
class addbase.__init __():
 self.fp = fp
 self.read = self.fp.read
 self.readline = self.fp.readline
 if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines
  self.fileno = self.fp.fileno
 # ... ...

可以看到, urllib.open 最终返回了 addbase, addbase 中没有对 socket 做任务处理, 不会有任何读写. 之后显示调用 read/readline/readlines, 才会从 web 服务器读取数据.

图 1. 初始化网络.

Python 仅获取响应头, 不获取实体的实例

图 2. urlopen() 之后

Python 仅获取响应头, 不获取实体的实例

图 3. read() 之后

Python 仅获取响应头, 不获取实体的实例

3. Use socket

看过 urllib 之后, 可以使用 socket 写一个方法, 只获取 header.

import socket
import ssl


_timeout = 10
socket.setdefaulttimeout(_timeout)

def get_header(host, port=80, uri="/", method="GET", user_ssl=False):
 # 这里可以再扩充一下, 支持 headers
 conn = None
 header = """%s %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36\r\n\r\n""" % (
  method, uri, host)
 if user_ssl:
  ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
  _socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  conn = ssl_context.wrap_socket(_socket, server_hostname=host)
  conn.connect((host, port))
  conn.send(header)
 else:
  conn = socket.create_connection((host, port), _timeout)
  conn.sendall(header)
 text = ""
 while True:
  if "\r\n\r\n" in text:
   break
  buff = conn.recv(10)
  text += buff
  # print buff
 conn.close()
 return text.split("\r\n\r\n")[0]

if __name__ == '__main__':
 print get_header("www.douban.com", uri="/subject/27076001/")
 print
 print get_header("www.douban.com", uri="/subject/27076001/", port=443, user_ssl=True)
➜ 76[14:48:20]zhipeng@zhipeng-MacBook ~/demo/python
�� $ python test_header.py
HTTP/1.1 301 Moved Permanently
Date: Fri, 13 Oct 2017 06:48:23 GMT
Content-Type: text/html
Content-Length: 178
Connection: close
Location: https://www.douban.com/subject/27076001/
Server: dae

HTTP/1.1 302 Moved Temporarily
Server: ADSSERVER/45863
Date: Fri, 13 Oct 2017 06:48:23 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: close
Location: https://sec.douban.com/b?r=https%3A%2F%2Fwww.douban.com%2Fsubject%2F27076001%2F
Strict-Transport-Security: max-age=15552000;
Set-Cookie: __ads_session=uY8l3pLW/AjCKJ8Y4wA=; domain=.douban.com; path=/
X-Powered-By-ADS: uni-jnads-1-02
➜ 77[14:48:23]zhipeng@zhipeng-MacBook ~/demo/python 
�� $

参考

<< Python socket server handle HTTPS request >> (https://stackoverflow.com/questions/32062925/python-socket-server-handle-https-request)

以上这篇Python 仅获取响应头, 不获取实体的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现DES加密解密方法实例详解
Jun 30 Python
使用简单工厂模式来进行Python的设计模式编程
Mar 01 Python
Python实现二分查找与bisect模块详解
Jan 13 Python
python网络爬虫 Scrapy中selenium用法详解
Sep 28 Python
python3.7 openpyxl 删除指定一列或者一行的代码
Oct 08 Python
python字符串,元组,列表,字典互转代码实例详解
Feb 14 Python
Flask模板引擎Jinja2使用实例
Apr 23 Python
python如何使用腾讯云发送短信
Sep 17 Python
python中random.randint和random.randrange的区别详解
Sep 20 Python
Python LMDB库的使用示例
Feb 14 Python
Python实现简单的猜单词
Jun 15 Python
python index() 与 rindex() 方法的使用示例详解
Dec 24 Python
详解用Python为直方图绘制拟合曲线的两种方法
Aug 21 #Python
Python 使用指定的网卡发送HTTP请求的实例
Aug 21 #Python
Python turtle绘画象棋棋盘
Aug 21 #Python
Python随机函数库random的使用方法详解
Aug 21 #Python
Django+zTree构建组织架构树的方法
Aug 21 #Python
python的移位操作实现详解
Aug 21 #Python
基于Python的微信机器人开发 微信登录和获取好友列表实现解析
Aug 21 #Python
You might like
PHP goto语句简介和使用实例
2014/03/11 PHP
PHP面向对象之事务脚本模式(详解)
2017/06/07 PHP
PHP实现的策略模式简单示例
2017/08/25 PHP
PHP中SESSION过期设置
2021/03/09 PHP
一个小型js框架myJSFrame附API使用帮助
2008/06/28 Javascript
JS 自定义带默认值的函数
2011/07/21 Javascript
jquery 如何动态添加、删除class样式方法介绍
2012/11/07 Javascript
使用JS读秒使用示例
2013/09/21 Javascript
jQuery源码分析之jQuery中的循环技巧详解
2014/09/06 Javascript
javascript面向对象之this关键词用法分析
2015/01/13 Javascript
jquery Banner轮播选项卡
2016/12/26 Javascript
JavaScript编写一个贪吃蛇游戏
2017/03/09 Javascript
在vue项目中使用Nprogress.js进度条的方法
2018/01/31 Javascript
使用javascript做在线算法编程
2018/05/25 Javascript
让webpack+vue-cil项目不再自动打开浏览器的方法
2018/09/27 Javascript
小程序从手动埋点到自动埋点的实现方法
2019/01/24 Javascript
JavaScript 九种跨域方式实现原理
2019/02/11 Javascript
js+html实现周岁年龄计算器
2019/06/25 Javascript
解决layer弹出层msg的文字不显示的问题
2019/09/11 Javascript
vue实现简单的登录弹出框
2020/10/26 Javascript
利用vue3+ts实现管理后台(增删改查)
2020/10/30 Javascript
CentOS 8.2服务器上安装最新版Node.js的方法
2020/12/16 Javascript
[01:08]2014DOTA2展望TI 剑指西雅图LGD战队专访
2014/06/30 DOTA
Python使用百度API上传文件到百度网盘代码分享
2014/11/08 Python
Python和JavaScript间代码转换的4个工具
2016/02/22 Python
Matplotlib scatter绘制散点图的方法实现
2020/01/02 Python
Python Django view 两种return的实现方式
2020/03/16 Python
工业自动化毕业生自荐信范文
2014/01/04 职场文书
大学毕业感言
2014/01/10 职场文书
应用化学专业职业生涯规划书
2014/01/22 职场文书
会议活动邀请函
2014/01/27 职场文书
爱我中华教学反思
2014/04/28 职场文书
写给女朋友的检讨书
2015/05/06 职场文书
2016年禁毒宣传活动总结
2016/04/05 职场文书
开学季:喜迎新生,迎新标语少不了
2019/11/07 职场文书
浅析MongoDB之安全认证
2021/06/26 MongoDB