【问题标题】:How to decode a source code which is compressed with gzip in python如何在python中解码用gzip压缩的源代码
【发布时间】:2016-05-19 07:43:51
【问题描述】:

我正在尝试使用代理获取 php 网页的源代码,但它显示不可打印的字符。我得到的输出如下:

 "日期:2016 年 2 月 9 日星期二 10:29:14 GMT
服务器:Apache/2.4.9 (Unix) OpenSSL/1.0.1g PHP/5.5.11 mod_perl/2.0.8-dev Perl/v5.16.3
X-Powered-By: PHP/5.5.11
设置 Cookie:PHPSESSID=jmqasueos33vqoe6dbm3iscvg0;路径=/
到期:1981 年 11 月 19 日星期四 08:52:00 GMT
缓存控制:无存储,无缓存,必须重新验证,后检查 = 0,预检查 = 0
Pragma:无缓存
内容编码:gzip
变化:接受编码
内容长度:577
保活:超时=5,最大值=99
连接:保持活动
内容类型:文本/html

 �TMo�@�G����7�)P�H�H�DS��=U�=�U�]˻��_�Ycl�T�*�>��eg�� 
                                                           ������ 
                                                                “V�N�f�:6�ԫ�IkZ77�A��nG�W��ɗ���RGY��Oc`-ο�ƜO��~?�V��$
                             �l4�+����n�].W��TLJSx�/|�n��#���>��r����;�l����H��4��f�\ “SY�y��7��” 

如何用python解码这段代码,我试过用

decd=zlib.decompress(data, 16+zlib.MAX_WBITS) 

但没有给出解码数据

我正在使用的代理在少数其他 Web 应用程序中运行良好。它显示某些 Web 应用程序的不可打印字符,如何解码?

当我使用代理时,我不想使用 get() 和 urlopen() 或来自 python 程序的任何其他请求。

【问题讨论】:

  • 您如何检索 URL?如果您使用requests 模块,内容将自动为您解压。
  • 所以你只想知道如何解压HTTP响应的正文?输入是什么?它是整个 HTTP 响应,包括标头,还是只是压缩的正文?您传递给zlib.decompress()data 中包含什么?
  • @mhawke .. 我的代理将获得整个 HTTP 响应,我想解码压缩的正文。当我使用 get 函数发送同一页面的请求时,我得到的是普通的 HTML 源代码,但是当我使用代理时,它显示了上述内容。
  • data 中有什么内容?如果data 只包含压缩后的数据,zlib.decompress(data, 16+zlib.MAX_WBITS) 应该会成功解压数据。或者您可以使用gzip 模块,如我的回答中所示。但是你在 data 中传递了什么?
  • @mhawke ..
    data
    包含上面显示的信息,以 url 名称、日期甚至不可打印字符开始

标签: php python html gzip compression


【解决方案1】:

一个明显的方法是从响应中提取压缩数据并使用GzipFile().read()解压缩它。这种拆分响应的方法可能容易失败,但在这里:

from gzip import GzipFile
from StringIO import StringIO

http = 'HTTP/1.1 200 OK\r\nServer: nginx\r\nDate: Tue, 09 Feb 2016 12:02:25 GMT\r\nContent-Type: application/json\r\nContent-Length: 115\r\nConnection: close\r\nContent-Encoding: gzip\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\n\r\n\x1f\x8b\x08\x00\xa0\xda\xb9V\x02\xff\xab\xe6RPPJ\xaf\xca,(HMQ\xb2R()*M\xd5Q\x00\x89e\xa4&\xa6\xa4\x16\x15\x03\xc5\xaa\x81\\\xa0\x80G~q\t\x90\xa7\x94QRR\x90\x94\x99\xa7\x97_\x94\xae\x04\x94\xa9\x85(\xcfM-\xc9\xc8\x07\x99\xa0\xe4\xee\x1a\xa2\x04\x11\xcb/\xcaL\xcf\xcc\x03\x89\x19Z\x1a\xe9\x19\x9aY\xe8\x19\xea\x19*q\xd5r\x01\x00\r(\xafRu\x00\x00\x00'

body = http.split('\r\n\r\n', 1)[1]
print GzipFile(fileobj=StringIO(body)).read()

输出

{ “压缩包”:是的, “标题”:{ “主机”:“httpbin.org” }, “方法”:“获取”, “起源”:“192.168.1.1” }

如果你觉得有必要解析完整的 HTTP 响应消息,那么,受this answer 的启发,这里有一个相当迂回的方法,它涉及直接从原始 HTTP 响应构造一个 httplib.HTTPResponse,使用它来创建urllib3.response.HTTPResponse,然后访问解压后的数据:

import httplib
from cStringIO import StringIO
from urllib3.response import HTTPResponse

http = 'HTTP/1.1 200 OK\r\nServer: nginx\r\nDate: Tue, 09 Feb 2016 12:02:25 GMT\r\nContent-Type: application/json\r\nContent-Length: 115\r\nConnection: close\r\nContent-Encoding: gzip\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\n\r\n\x1f\x8b\x08\x00\xa0\xda\xb9V\x02\xff\xab\xe6RPPJ\xaf\xca,(HMQ\xb2R()*M\xd5Q\x00\x89e\xa4&\xa6\xa4\x16\x15\x03\xc5\xaa\x81\\\xa0\x80G~q\t\x90\xa7\x94QRR\x90\x94\x99\xa7\x97_\x94\xae\x04\x94\xa9\x85(\xcfM-\xc9\xc8\x07\x99\xa0\xe4\xee\x1a\xa2\x04\x11\xcb/\xcaL\xcf\xcc\x03\x89\x19Z\x1a\xe9\x19\x9aY\xe8\x19\xea\x19*q\xd5r\x01\x00\r(\xafRu\x00\x00\x00'

class DummySocket(object):
    def __init__(self, data):
        self._data = StringIO(data)
    def makefile(self, *args, **kwargs):
        return self._data

response = httplib.HTTPResponse(DummySocket(http))
response.begin()
response = HTTPResponse.from_httplib(response)
print(response.data)

输出

{ “压缩包”:是的, “标题”:{ “主机”:“httpbin.org” }, “方法”:“获取”, “起源”:“192.168.1.1” }

【讨论】:

  • 实际上我正在使用代理,通过它我可以在浏览器中捕获 url 的源代码。如果我使用来自 python 程序的请求,我可以获得,但我想自动捕获我在浏览器中访问的所有页面。
  • @krocks:我已经用 2 种适合你的方法更新了我的答案。
【解决方案2】:

虽然gzip 使用zlib,但当Content-Encoding 设置为gzip 时,在zlib.decompress 调用未正确解释的压缩流之前还有一个附加标头。

将您的数据放入file-like 对象中并通过gzip 模块传递。例如:

mydatafile = cStringIO.StringIO(data)
gzipper = gzip.GzipFile(fileobj=mydatafile)
decdata = gzipper.read()

来自我已经很旧的 Python 2.x http 库

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 2016-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    相关资源
    最近更新 更多