博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于chunked gzip,socket下载网页内容.
阅读量:7029 次
发布时间:2019-06-28

本文共 1894 字,大约阅读时间需要 6 分钟。

关于chunked gzip,socket下载网页内容. - xiqi8144的专栏 - 博客频道 - CSDN.NET

    关于chunked gzip,socket下载网页内容.
    在利用底层socket下载html网页的时候,java,python都有很方面的类库操作,可以如果是利用c++来写,就必须要利用socket,底层的操作,首先建立socket,然而,发送响应的request header,模拟浏览器的请求也可,只需将user-agent,修改浏览器的名称,比如ie,比如firefox,也可以是rober,比如搜索引擎的名称,这些东西网上很多,不再写了,这里只写关于chunked的数据提取与解压.
    如果我们请求的头之中,有Accept-Encoding, gzip, deflate,并且对方的服务器支持gzip方式的数据话,服务器就会以gzip的方式为客户端传输数据,在客户端浏览器会为我们解压,通过情况下,服务器都会带上Content-Length代表所需要求发送的数据的长度,客户的socket从响应头之中取出这个数据,作为一个标准,需要从服务器接收多少字节的数据,但是,有时候,服务器不会带上这个响应头,但是却带上了另一个响应头Transfer-encoding: chunked,代表数据是以chunk的方式进行传输的。
    所谓的chunk是如下的格式:
    第一个chunk数据的字节数+/r/n+第一个chunk的数据+第二个chunk的数据的字节数+/r/n+数据+n个chunk+/r/n+0+/r/n。
    因此,接收的时候,需要首先获取每一个字节的长度,然后,跳过2个字节,取出数据,然后,再跳过2个字节,获取下一个chunk的长度,直到最后一个chunk,最后一个chunk一定是0,并且字节的长度都是十六进制形式传输,需要进行相应的转化成十进制,如果是gzip格式的数据,那么,在最后完成所有数据组合之后,需要再解压,如果不是以chunk方式的传输,直接解压即可.
    在网上google了半天,转载最多的是下面的一篇http://www.donevii.com/post/468.html,但是,并没有相应的处理代码,在此记下我的处理的代码.
    [python] view plaincopyprint?
        if(chunk==True): 
            content=content.lstrip('/r') 
            content=content.lstrip('/n') 
            #获取第一个chunk的十六进制长度str,以/r/n结束. 
            temp=content.find('/r/n') 
            strtemp=content[0:temp] 
            readbytes=int(strtemp,16)#转化成十进制 
            newcont='' 
            start=2 
            offset=temp+2 
            newcont='' 
            #循环处理所有的chunk 
            while(readbytes>0): 
                #获取这一部分数据,与以前数据拼加. 
                newcont+=content[offset:readbytes+offset] 
                offset+=readbytes 
                endtemp=content.find('/r/n',offset+2) 
                if(endtemp>-1): 
                    strtemp=content[offset+2:endtemp] 
                    readbytes=int(strtemp,16) 
                    if(readbytes==0): 
                        break 
                    else: 
                        offset=endtemp+2 
            #代替以前的数据. 
            content=newcont 
            #print 'adfafa'+content 
        print contentType 
        try: 
            #如果是gzip方式的数据,需要解压,如果是chunked的数据,不进行上面的操作,直接解压是不能正 
              #常解压的. 
            if(contentType=='gzip'): 
                compressedstream = StringIO.StringIO(content) 
                gzipper = gzip.GzipFile(fileobj=compressedstream)  
                content=gzipper.read() 
                 
        except IOError,e: 
            print e 
    以上就是部分python的socket的下载数据部分代码,关于在于需要提取每一个chunk的长度,然后,提取数据,如果还有下一个chunk,接着处理,直到最后的一个chunk以/r/n+0+/r/n结束,代表所有的chunk已经传递完毕.

你可能感兴趣的文章
PHP经验——PHPDoc PHP注释的标准文档(翻译自Wiki)
查看>>
vue input输入框长度限制
查看>>
深入理解Java虚拟机(类加载机制)
查看>>
在500jsp错误页面获取错误信息
查看>>
iOS-CALayer遮罩效果
查看>>
为什么需要版本管理
查看>>
五、Dart 关键字
查看>>
React Native学习笔记(一)附视频教学
查看>>
记Promise得一些API
查看>>
javascript事件之调整大小(resize)事件
查看>>
20145234黄斐《Java程序设计》第六周学习总结
查看>>
【CLRS】《算法导论》读书笔记(四):栈(Stack)、队列(Queue)和链表(Linked List)...
查看>>
hibernate 和 mybatis区别
查看>>
互联网广告综述之点击率特征工程
查看>>
HDU3421 Max Sum II【序列处理】
查看>>
POJ NOI MATH-7653 地球人口承载力估计
查看>>
iOS UI高级之网络编程(HTTP协议)
查看>>
使用cocoaPods import导入时没有提示的解决办法
查看>>
iOS数据持久化存储之归档NSKeyedArchiver
查看>>
JavaScript面向对象
查看>>