python2.7 urllib 2のconnection自動closeの原因と解決方法
11694 ワード
前述したurllib 2の一般的な問題の解決策について説明したが、今日はurllib 2における短い接続の問題について特に議論する.
以下のコードに示すように、「Connection」:「keep-alive」をカスタマイズし、サーバインタラクションが終了したことを通知した後、接続を継続します.つまり、いわゆる長接続です.
出力メッセージ:
注意ログのダッシュ部分には、User-agentなどの要求メッセージの他のヘッダが変更されましたが、connectionはcloseを維持しています. Connection: close header: Connection: close
httplib 2プロトコルのコードに置き換えると、もちろんurllib 2がkeep-aliveをサポートしない解決策の一つであり、もう一つの方法はRequestsである.
出力では、長接続設定に成功していることがわかります. header: Connection: Keep-Alive
やはりurllib 2のソースコードに行きましょう.do_に見えます.Openコアメソッドではconnectionがcloseと書かれています.理由は上の注釈の山で、addinfourlというクラスが長いリンクを有効にすると、前回インタラクティブで未読の応答メッセージを読み取ることができ、このような状況を防ぐために、強制的にConnectionをcloseに書くことを意味します. def do_open(self, http_class, req, **http_conn_args): …… # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = dict((name.title(), val) for name, val in headers.items()) if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: h.request(req.get_method(), req.get_selector(), req.data, headers)
転載先:https://www.cnblogs.com/zhongtang/articles/5495181.html
1、urllib 2コード
以下のコードに示すように、「Connection」:「keep-alive」をカスタマイズし、サーバインタラクションが終了したことを通知した後、接続を継続します.つまり、いわゆる長接続です.
1 # 8 urllib2 Connection=keep-alive
2 import urllib2
3 import cookielib
4
5
6 httpHandler = urllib2.HTTPHandler(debuglevel=1)
7 httpsHandler = urllib2.HTTPSHandler(debuglevel=1)
8 opener = urllib2.build_opener(httpHandler, httpsHandler)
9 urllib2.install_opener(opener)
10
11 loginHeaders={
12 'User-Agent': 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.0 Chrome/30.0.1599.101 Safari/537.36',
13 'Referer': 'https://www.baidu.com',
14 'Connection': 'keep-alive'
15 }
16 request=urllib2.Request('http://www.suning.com.cn',headers=loginHeaders)
17 response = urllib2.urlopen(request)
18 page=''
19 page= response.read()
20 print response.info()
21 print page
出力メッセージ:
注意ログのダッシュ部分には、User-agentなどの要求メッセージの他のヘッダが変更されましたが、connectionはcloseを維持しています.
1 send: 'GET / HTTP/1.1\r
Accept-Encoding: identity\r
Host: www.suning.com.cn\r
Connection: close\r
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.0 Chrome/30.0.1599.101 Safari/537.36\r
\r
'
2 reply: 'HTTP/1.1 200 OK\r
'
3 header: Connection: close
4 header: Transfer-Encoding: chunked
5 header: Expires: Thu, 19 Nov 1981 08:52:00 GMT
6 header: Date: Sun, 15 May 2016 06:09:43 GMT
7 header: Content-Type: text/html; charset=utf-8
8 header: Server: nginx/1.2.9
9 header: Vary: Accept-Encoding
10 header: X-Powered-By: ThinkPHP
11 header: Set-Cookie: PHPSESSID=tv7ced9sbu7lph60o8ilfj4207; path=/
12 header: Cache-Control: private
13 header: Pragma: no-cache
14 doctype html>
15 <html lang="zh-CN">
16 <head>
17 <meta charset="utf-8">
18 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
2、httplib 2書き方コード
httplib 2プロトコルのコードに置き換えると、もちろんurllib 2がkeep-aliveをサポートしない解決策の一つであり、もう一つの方法はRequestsである.
1 # 9 httplib2 Connection=keep-alive
2 import httplib2
3
4 ghttp = httplib2.Http()
5 httplib2.debuglevel=1
6 loginHeaders={
7 'User-Agent': 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.0 Chrome/30.0.1599.101 Safari/537.36',
8 'Connection': 'keep-alive'
9 }
10
11 response ,page= ghttp.request('http://www.suning.com.cn',headers=loginHeaders )
12 print page.decode('utf-8')
出力では、長接続設定に成功していることがわかります.
1 connect: (www.suning.com.cn, 80) ************
2 send: 'GET / HTTP/1.1\r
Host: www.suning.com.cn\r
connection: keep-alive\r
accept-encoding: gzip, deflate\r
user-agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.0 Chrome/30.0.1599.101 Safari/537.36\r
\r
'
3 reply: 'HTTP/1.1 200 OK\r
'
4 header: Connection: Keep-Alive
5 header: Transfer-Encoding: chunked
6 header: Expires: Thu, 19 Nov 1981 08:52:00 GMT
7 header: Date: Sun, 15 May 2016 06:15:16 GMT
8 header: Content-Type: text/html; charset=utf-8
9 header: Server: nginx/1.2.9
10 header: Vary: Accept-Encoding
11 header: X-Powered-By: ThinkPHP
12 header: Set-Cookie: PHPSESSID=ep580j8bq3uba0ud3fe3rgu5i5; path=/
13 header: Cache-Control: private
14 header: Pragma: no-cache
3、原因を分析する
やはりurllib 2のソースコードに行きましょう.do_に見えます.Openコアメソッドではconnectionがcloseと書かれています.理由は上の注釈の山で、addinfourlというクラスが長いリンクを有効にすると、前回インタラクティブで未読の応答メッセージを読み取ることができ、このような状況を防ぐために、強制的にConnectionをcloseに書くことを意味します. def do_open(self, http_class, req, **http_conn_args): …… # We want to make an HTTP/1.1 request, but the addinfourl # class isn't prepared to deal with a persistent connection. # It will try to read all remaining data from the socket, # which will block while the server waits for the next request. # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" headers = dict((name.title(), val) for name, val in headers.items()) if req._tunnel_host: tunnel_headers = {} proxy_auth_hdr = "Proxy-Authorization" if proxy_auth_hdr in headers: tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] # Proxy-Authorization should not be sent to origin # server. del headers[proxy_auth_hdr] h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: h.request(req.get_method(), req.get_selector(), req.data, headers)
転載先:https://www.cnblogs.com/zhongtang/articles/5495181.html