Python for Infomatics第12章ネットワークプログラミング二(訳)

6404 ワード

注:本文はDr.Charles Severanceの「Python for Informatics」.本文中のコードは3.4版で書き換え、本機でテストに合格した.
12.3 HTTPプロトコルで1枚の画像を取得する
前節の例では、改行文字のあるテキストファイルを取得し、画面に簡単に表示します.同様に、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

') 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
\r
") 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 51205120 102405120 153605120 204805120 256005120 30720960 316805120 368005120 419202384 443043752 480565120 531765120 582965120 634165120 685361767 70303Header length 242HTTP/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()を連続的に呼び出す間隔を遅らせます.このようにして、recv()を呼び出す前にサーバがより多くのデータを送信するのに間に合うように、呼び出すたびに1/4秒待ちます.遅延を追加したプログラムの実行結果は次のとおりです.
5120 5120
5120 10240....5120 665603743 70303Header length 242HTTP/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によるWebページの取得
HTTPプロトコル上でsocketライブラリを使用してデータを手動で送信および受信できますが、Pythonではurllibライブラリを使用してこの一般的なタスクを完了するのはより簡単です.
urllibを使うと、ページをファイルと見なすことができます.どのページがほしいかを簡単に指摘すれば、残りはurllibが処理します.
romeoをsocketで読み出す.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 breaksIt is the east and Juliet is the sunArise fair sun and kill the envious moonWho 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}
もう一度説明しますが、このページを開くと、ローカルドキュメントのように読み取ることができます.  
転載先:https://www.cnblogs.com/zhengsh/p/5424261.html