注:文章原文为Dr. Charles Severance 的 《Python for Informatics》。文中代码用3.4版改写,并在本机测试通过。

12.3 用HTTP协议获取一张图片

  在上一节的例子中,我们获取的是一个有换行符的文本文件,并简单的把它显示在屏幕上。同样我们可以用一个小程序通过HTTP协议获取图片。下面这个程序运行时,不是直接在屏幕上显示数据,而是剔除头信息,然后将收到的数据合并保存为一个图片文件。具体代码如下:

import socket
import time mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.py4inf.com', 80))
mysock.send(b'GET http://www.py4inf.com/cover.jpg HTTP/1.0\n\n') count = 0
picture = b""
while True:
data = mysock.recv(5120)
if ( len(data) < 1 ) :
break
# time.sleep(0.25)
count = count + len(data)
print(len(data), count)
picture = picture + data
mysock.close() # Look for end of the header (2 CRLF)
pos = picture.find(b"\r\n\r\n")
print('Header length', pos)
print(picture[:pos].decode("utf-8")) # Skip past the header and save the picture
picture = picture[pos+4:]
fhand = open("stuff.jpg", "wb")
fhand.write(picture)
fhand.close()

运行程序,输出如下:

5120 5120
5120 10240
5120 15360
5120 20480
5120 25600
5120 30720
960 31680
5120 36800
5120 41920
2384 44304
3752 48056
5120 53176
5120 58296
5120 63416
5120 68536
1767 70303
Header length 242
HTTP/1.1 200 OK

Date: Sat, 23 Apr 2016 06:51:38 GMT

Server: Apache

Last-Modified: Fri, 04 Dec 2015 19:05:04 GMT

ETag: "b294001f-111a9-526172f5b7cc9"

Accept-Ranges: bytes

Content-Length: 70057

Connection: close

Content-Type: image/jpeg

  正如你看到的,它的内容类型头信息表明这个文档的主体是一张图片。一旦程序运行结束,你就可以用图片查看器打开stuff.jpg文件,你会发现这是本书的封面。

  从程序运行过程中,可以看到我们并不是每次都接收到5120个字符。在我们调用recv()方法的那个时刻,我们收到的字符数和网页服务器发给我们的一样多。在这个例子中有960,2384到最多5120个字符。因为你的网速会有所不同,所以你的输出也会不同。同时要注意的是我们收到的最后一批码流是1767个,下一次调用recv()我们将收到零长度的字符串,这告诉我们服务器已调用close()关闭了它那端的套接字,并且不会再有数据发送过来。

  我们可以取消time.sleep()的注释,减缓我们连续调用recv()的时间间隔。通过这种方式,我们在每次调用前等待1/4秒,从而让服务器赶上我们在调用recv()之前发送更多的数据。添加延时后程序的运行结果如下:

5120 5120

5120 10240
....
5120 66560
3743 70303
Header length 242
HTTP/1.1 200 OK

Date: Sat, 23 Apr 2016 07:38:55 GMT

Server: Apache

Last-Modified: Fri, 04 Dec 2015 19:05:04 GMT

ETag: "b294001f-111a9-526172f5b7cc9"

Accept-Ranges: bytes

Content-Length: 70057

Connection: close

Content-Type: image/jpeg

  现在除了最后一次调用少于5120外,其它我们每次都接收到5120个(注:可能是网速的原因,译者的第一次接收也是5120个,而原文中第一次也小于5120)。这是服务器的发送和我们的接收共同约定的缓冲区容量。当我们采用延时接收时,在某些时刻服务器的发送可能填满这个缓冲区,从而不得不停止发送,只到我们的程序清空缓冲区。这个在发送和接收程序间的停顿被叫做流量控制。

12.4 用urllib获取网页

  虽然我们可以用socket库在HTTP协议上人工发送和接收数据,但是在Python中用urllib库来完成这项常见任务来得更加简单。

  用urllib,你可以把网页看作是一个文件,你只要简单地指出你要哪个网页,剩下的就由urllib来处理了。

  与用socket读取romeo.txt具备相同功能的urllib代码如下:

import urllib.request
fhand = urllib.request.urlopen('http://www.py4inf.com/code/romeo.txt')
for line in fhand:
print(line.strip().decode('utf-8'))

  一旦这个网页被urllib.request.urlopen打开,我们就可以把它看作一个文件,并且循环读取。

  当运行这个程序时,我们只能看到文件的内容。虽然文件头仍然被发送,但是urllib代码消除了文件头,只返回以下内容:  

But soft what light through yonder window breaks
It is the east and Juliet is the sun
Arise fair sun and kill the envious moon
Who is already sick and pale with grief

  下个例子中,我们在获取romeo.txt之后,计算文件中每个词出现的频率:

import urllib.request
counts = dict()
fhand = urllib.request.urlopen('http://www.py4inf.com/code/romeo.txt')
for line in fhand:
words = line.decode('utf-8').split()
for word in words:
counts[word] = counts.get(word,0) + 1
print (counts)

  代码的输出结果如下:

{'is': 3, 'kill': 1, 'light': 1, 'sun': 2, 'Arise': 1, 'moon': 1, 'It': 1, 'yonder': 1, 'the': 3, 'But': 1, 'fair': 1, 'and': 3, 'east': 1, 'soft': 1, 'Juliet': 1, 'grief': 1, 'already': 1, 'breaks': 1, 'envious': 1, 'sick': 1, 'pale': 1, 'what': 1, 'through': 1, 'Who': 1, 'with': 1, 'window': 1}

  再次说明,一旦我们打开了这个网页,我们就可以像本地文档一样读取它。  

Python for Infomatics 第12章 网络编程二(译)的更多相关文章

  1. Python for Infomatics 第12章 网络编程一(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 本书中的许多例子关注的是读取文件 ...

  2. Python for Infomatics 第12章 网络编程六(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 12.9 词汇表 Beautif ...

  3. Python for Infomatics 第12章 网络编程五(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 12.8 用urllib读取二进 ...

  4. Python for Infomatics 第12章 网络编程四(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 12.7 用BeautifulS ...

  5. Python for Infomatics 第12章 网络编程三(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 12.5 HTML分析和网页抓取 ...

  6. python之路(12)网络编程

    前言 基于网络通信(AF_INET)的socket(套接字)实现了TCP/UDP协议 目录 基于TCP协议的socket 基于UDP协议的socket TCP协议下粘包现象及处理 使用socketse ...

  7. Python for Infomatics 第13章 网页服务二(译)

    注:文章原文为Dr. Charles Severance 的 <Python for Informatics>.文中代码用3.4版改写,并在本机测试通过. 13.4 JavaScript ...

  8. CSAPP:第十一章 网络编程

    CSAPP:第十一章 网络编程 11.1 客户端服务器模型11.2 全球IP因特网11.3 套接字接口 11.1 客户端服务器模型   每个网络应用都是基于客户端-服务器模型.采用这个模型,一个应用是 ...

  9. Python学习day34-面向对象和网络编程总结

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

随机推荐

  1. 30个要点帮你完成java代码优化

    通过java代码规范来优化程序,优化内存使用情况,防止内存泄露 可供程序利用的资源(内存.CPU时间.网络带宽等)是有限的,优化的目的就是让程序用尽可能少的资源完成预定的任务.优化通常包含两方面的内容 ...

  2. Web jquery表格组件 JQGrid 的使用 - 6.准备工作 & Hello JQGrid

    系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件 ...

  3. 线程安全的无锁RingBuffer的实现

    这里的线程安全,是指一个读线程和一个写线程,读写两个线程是安全的,而不是说多个读线程和多个写线程是安全的.. 在程序设计中,我们有时会遇到这样的情况,一个线程将数据写到一个buffer中,另外一个线程 ...

  4. [Network] HTML、XML和JSON学习汇总

    写在前面:楼主也是刚刚接触这方面的知识,之前完全是零基础,后来经朋友推荐了几个不错的博文,看完以后豁然开朗.但是此博文更加偏重于基础知识介绍(其实更深的楼主也还不了解,这方面的大神请绕道),只是分享个 ...

  5. CSS高效开发实战:CSS 3、LESS、SASS、Bootstrap、Foundation --读书笔记(1)设定背景图

    技术的新发展,除计算机可以接入互联网之外,平板电脑.智能手机.智能电视等其他设备均可访问互联网.在多设备时代,构建多屏体验也不是听说的那么难. 但是这也增加了学习CSS的难度?不知道如何上手,只懂一点 ...

  6. saltstack(主机改名)

    已存在salt中的机器,为了规范,需要将这批主机改名 操作流程:在master把这批机器剔除:然修改这批机器的主机名.在/etc/salt目录下.用mv把minion_id和pki的目录重命名.重启s ...

  7. hash模块 hashlib 和hmac

    hashlib模块 用于加密相关的操作,代替md5模块和sha模块,主要提供SHA1,SHA224,SSHA256,SHA384,SHA512,MD5算法 直接看代码案例: ---------md5- ...

  8. centOS 虚拟机设置固定IP:图形化设置

    右键单击图形化标志,Edit Connection 设置一下就可以了.

  9. 【python】继承关系和isinstance

    来源:廖雪峰 继承关系是: object -> Animal -> Dog -> Husky 那么,isinstance()就可以告诉我们,一个对象是否是某种类型.先创建3种类型的对 ...

  10. 【Objective-C】NSDate详解及获取当前时间等常用操作

    NSDate类用于保存时间值,同时提供了一些方法来处理一些基于秒级别时差(Time Interval)运算和日期之间的早晚比较等. 1. 创建或初始化可用以下方法 用于创建NSDate实例的类方法有 ...