第14.7节 Python模拟浏览器访问实现http报文体压缩传输
一、	引言
在《第14.6节 Python模拟浏览器访问网页的实现代码》介绍了使用urllib包的request模块访问网页的方法。但上节特别说明http报文头Accept-Encoding最好不设置,否则服务端会根据该字段及服务端的情况采用对应方式压缩http报文体,如果爬虫应用没有解压支持会导致应用无法识别收到的响应报文体。本节简单介绍一下怎么处理响应报文体的压缩。
在爬虫爬取网页时,如果在请求头中传递了“‘Accept-Encoding’:‘gzip’”信息则服务器会采用gzip压缩报文,此时客户端必须支持对报文解压缩才能识别报文。解gzip压缩需要安装gzip模块,并在服务器返回http应答报文时判断服务端是否压缩了报文,如果压缩了就进行解压处理,否则直接读取。
二、	对HTTP响应报文的报文体支持压缩处理的爬虫处理步骤
要进行响应HTTP报文体的压缩,爬虫应用需要进行如下处理:
1、	在请求报文的http报文头中的Accept-Encoding中设置能支持的压缩格式;
2、	读取响应报文后要判断响应报文头中的Content-Encoding的返回值的压缩格式;
3、	调用对应的解压方法进行报文体解压。
三、	案例
1、	导入相关模块:
import urllib.request
from io import BytesIO
import gzip
2、	构造支持压缩的请求报文头
本节在《第14.5节 利用浏览器获取的http信息构造Python网页访问的http请求头》的mkhead函数的基础上,增加一个参数来确认是否需要处理压缩报文,如果是则通过http报文头的Accept-Encoding参数向服务器告知支持的压缩格式,否则不设置压缩格式支持的请求报文头Accept-Encoding参数,代码如下:
  def mkhead(NeedEncoding=False):
    if NeedEncoding:
        header = {'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
        'Accept-Encoding':'gzip',
        'Accept-Language':'zh-CN,zh;q=0.9',
        'Connection':'keep-alive',
        'Cookie':'uuid_tt_dd=10_35489889920-1563497330616-876822;......',
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}
    else:
        header = {'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
        'Accept-Language':'zh-CN,zh;q=0.9',
        'Connection':'keep-alive',
        'Cookie':'uuid_tt_dd=10_35489889920-1563497330616-876822;......',
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}
    return header
3、 读取响应报文后取响应报文头中的Content-Encoding的返回值的压缩格式
 req = urllib.request.Request(url=site,headers=header)
   sitersp = urllib.request.urlopen(req)
   Encoding = sitersp.info().get('Content-Encoding')  #取响应报文体的压缩格式
4、 根据压缩对应情况进行处理后返回报文体的内容,如果是gzip压缩就调用gzip解压,如果未压缩就不进行解压处理,否则报错返回:
 if  Encoding== 'gzip':  #判断压缩格式是否gzip格式
        print(" Encoding== 'gzip'")
        buf = BytesIO(sitersp.read())
        fzip = gzip.GzipFile(fileobj=buf)
        return fzip.read().decode()
    elif not Encoding:  #是否没有压缩报文体
        print(" Encoding==None")
        return sitersp.read().decode()
    else:
        print(f"Content-Encoding={Encoding},can't unzip")
        return None
四、 案例完整代码
#读取压缩http响应报文
import urllib.request
from io import BytesIO
import gzip
def mkhead(NeedEncoding=False):
    if NeedEncoding:
        header = {'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
        'Accept-Encoding':'gzip',
        'Accept-Language':'zh-CN,zh;q=0.9',
        'Connection':'keep-alive',
        'Cookie':'uuid_tt_dd=10_35489889920-1563497330616-876822;...... ',
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}
    else:
        header = {'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
        'Accept-Language':'zh-CN,zh;q=0.9',
        'Connection':'keep-alive',
        'Cookie':'uuid_tt_dd=10_35489889920-1563497330616-876822;......',
        'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}
    return header 
def readweb(site):
    header = mkhead(True)
    try:
        req = urllib.request.Request(url=site,headers=header)
        sitersp = urllib.request.urlopen(req)
    except Exception as e:
        print(e)
        return None
    Encoding = sitersp.info().get('Content-Encoding')
    if  Encoding== 'gzip':
        print(" Encoding== 'gzip'")
        buf = BytesIO(sitersp.read())
        fzip = gzip.GzipFile(fileobj=buf)
        return fzip.read().decode()
    elif not Encoding:
        print(" Encoding==None")
        return sitersp.read().decode()
    else:
        print(f"Content-Encoding={Encoding},can't unzip")
        return None
readweb(r'https://blog.csdn.net/LaoYuanPython/article/details/100585881 ')[0:100]
执行结果:
>>> readweb(r'https://blog.csdn.net/LaoYuanPython/article/details/100585881 ')[0:100]
 Encoding== 'gzip'
'<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n    <meta charset="UTF-8">\n    <link rel="canonical" href'
>>>
注意:代码中的cookie设置可以不要,那就是匿名爬取网页,如果需要非匿名则需要根据自己浏览器的cookie来设置。
本节介绍了使用urllib包的request模块读取网页并支持解压的实现过程,以支持网页内容的压缩传输。
老猿Python,跟老猿学Python!
博客地址:https://blog.csdn.net/LaoYuanPython
老猿Python博客文章目录:https://blog.csdn.net/LaoYuanPython/article/details/98245036
请大家多多支持,点赞、评论和加关注!谢谢!
第14.7节 Python模拟浏览器访问实现http报文体压缩传输的更多相关文章
- python 模拟浏览器
		想用python模拟浏览器访问web的方法测试些东西,有哪几种方法呢? 一类:单纯的访问web,不解析其js,css等. 1. urllib2 #-*- coding:utf-8 -* import ... 
- 第14.6节 使用Python urllib.request模拟浏览器访问网页的实现代码
		Python要访问一个网页并读取网页内容非常简单,在利用<第14.5节 利用浏览器获取的http信息构造Python网页访问的http请求头>的方法构建了请求http报文的请求头情况下,使 ... 
- 第14.9节 Python中使用urllib.request+BeautifulSoup获取url访问的基本信息
		利用urllib.request读取url文档的内容并使用BeautifulSoup解析后,可以通过一些基本的BeautifulSoup对象输出html文档的基本信息.以博文<第14.6节 使用 ... 
- 第14.4节 使用IE浏览器获取网站访问的http信息
		上节<第14.3节 使用google浏览器获取网站访问的http信息>中介绍了使用Google浏览器怎么获取网站访问的http相关报文信息,本节介绍IE浏览器中怎么获取相关信息.以上节为基 ... 
- 第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问
		一. 引言 在<第14.8节 Python中使用BeautifulSoup加载HTML报文>中介绍使用BeautifulSoup的安装.导入和创建对象的过程,本节介绍导入后利用Beauti ... 
- 第14.12节 Python中使用BeautifulSoup解析http报文:使用select方法快速定位内容
		一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>和<第14.11节 Python中使用BeautifulSo ... 
- 第14.11节 Python中使用BeautifulSoup解析http报文:使用查找方法快速定位内容
		一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>介绍了BeautifulSoup对象的主要属性,通过这些属性可以访 ... 
- 第14.8节 Python中使用BeautifulSoup加载HTML报文
		一. 引言 BeautifulSoup是一个三方模块bs4中提供的进行HTML解析的类,可以认为是一个HTML解析工具箱,对HTML报文中的标签具有比较好的容错识别功能.阅读本节需要了解html相关的 ... 
- php -- php模拟浏览器访问网址
		目前我所了解到的在php后台中,用php模拟浏览器访问网址的方法有两种: 第一种:模拟GET请求:file_get_contents($url) 通过php内置的 file_get_contents ... 
随机推荐
- javascript-闭包【面试必备】
			闭包 定义:内层函数可以访问外层函数作用域的变量 意义/用途: 1.封装细节 2.实现模块化 3.常用实战li列表 // querySelectorAll es5支持的一个类似于jq的复杂选择器选取d ... 
- Oracle(第二天)
			一.外键(foreign key):constraint , refenerces 例如:sno number(7) constraint fk_sno references student(sno) ... 
- C语言中利用clock设计一个简单的定时器
			time.h是C/C++中的日期和时间头文件,用于需要时间方面的函数,定义了四个变量类型.两个宏和各种操作日期和时间的函数. 其中计时函数是clock(),而与其相关的数据类型是clock_t.clo ... 
- [Docker镜像] 关于阿里云容器镜像服务的使用(以天池比赛提交镜像为例)
			最近在参加天池比赛,由于比赛需要使用阿里云容器镜像服务完成线上预测任务,所以花费了3-4天的时间了解并使用Docker完成相关镜像操作,在此分享下我学习的内容,以下是本文的目录结构: 介绍 镜像 容器 ... 
- 基于CPU版本的Caffe推理框架
			最近一段时间,认真研究了一下caffe.但是,里面内容过多,集合了CPU版本和GPU版本的代码,导致阅读起来有些复杂.因此,特意对caffe代码进行了重构,搭建一个基于CPU版本的Caffe推理框架. ... 
- MySQL中EXPLAIN结果的参数详解
			explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了.如: mysql& ... 
- JAVA注解的继承性
			摘要 本文从三个方面介绍java注解的**"继承性"**: 基于元注解@Inherited,类上注解的继承性 基于类的继承,方法/属性上注解的继承性 基于接口的继承/实现,方法/属 ... 
- 基于gin的golang web开发:集成swagger
			在前后端分离的项目维护一份完整且及时更新的api文档会极大的提高我们的工作效率,传统项目中接口文档都是由后端开发手写的,这种文档很难保证及时性,久而久之便失去了参考意义.swagger给我们提供了一种 ... 
- CSS 常用列表样式
			CSS 常用列表样式 CSS没学扎实,复习记录一下.下面是一些常用的属性 list-style-image 指定一个图片作为列表项的标记 默认值none,可设置为图片的url list-style-i ... 
- [原题复现]BJDCTF2020 WEB部分全部解
			简介 原题复现:https://gitee.com/xiaohua1998/BJDCTF2020_January 线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学 ... 
