可以用下面的代碼來(lái)訪問(wèn)bilibili
import tornado.httpclient
http_client = tornado.httpclient.HTTPClient()
try:
response = http_client.fetch("http://www.bilibili.com/")
print response.body
except httpclient.HTTPError as e:
print "Error:", e
http_client.close()
看下輸出
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>嗶哩嗶哩彈幕視頻網(wǎng) - ( ゜- ゜)つロ 乾杯~ - bilibili</title>
<meta name="description" content="bilibili是一家彈幕站點(diǎn),大家可以在這里找到許多的歡樂(lè).">
<meta name="keywords" content="B站 彈幕 字幕 AMV MAD MTV ANIME 動(dòng)漫 動(dòng)漫音樂(lè) 游戲 游戲解說(shuō) ACG galgame 動(dòng)畫(huà) 番組 新番 初音 洛天依 vocaloid">
.......
恩是B站首頁(yè)沒(méi)錯(cuò)
我們來(lái)解析一下上面的代碼
首先是 http_client = tornado.httpclient.HTTPClient()
創(chuàng)建了一個(gè)HTTPClient實(shí)例
這個(gè)類(lèi)有兩個(gè)函數(shù)
def fetch(self, request, **kwargs)
其中的request可以是一個(gè)HTTPRequest 的實(shí)例或者是一個(gè)url的字符串
返回的是HTTPResponse對(duì)象
HTTPRequest和HTTPResponse
這兩個(gè)類(lèi)定義在httpclient.py 中 可以從源碼中看下是如何實(shí)現(xiàn)的
看下HTTPRequest的init(self)函數(shù):
def __init__(self, url, method="GET", headers=None, body=None,
auth_username=None, auth_password=None, auth_mode=None,
connect_timeout=None, request_timeout=None,
if_modified_since=None, follow_redirects=None,
max_redirects=None, user_agent=None, use_gzip=None,
network_interface=None, streaming_callback=None,
header_callback=None, prepare_curl_callback=None,
proxy_host=None, proxy_port=None, proxy_username=None,
proxy_password=None, allow_nonstandard_methods=None,
validate_cert=None, ca_certs=None,
allow_ipv6=None,
client_key=None, client_cert=None, body_producer=None,
expect_100_continue=False, decompress_response=None):
我們來(lái)看下關(guān)鍵的參數(shù)
- url 鏈接參數(shù)
- method 如POST GET 默認(rèn)為GET
- headers 請(qǐng)求的額外頭 可以是HTTPHeader 有决,也可以是個(gè)dict
HTTPResponse定義了許多字段
- request: 是一個(gè)HTTPRequest 的實(shí)例
- code: http狀態(tài)碼 e.g. 200 or 404
- reason: OK ERROR 什么的 原因解釋
- headers:響應(yīng)頭 是一個(gè) tornado.httputil.HTTPHeaders 實(shí)例
- effective_url: 經(jīng)過(guò)重定向之后的網(wǎng)址
- body: response body as string (created on demand from self.buffer)
- error: 如果出錯(cuò) 則存在Exception 的實(shí)例,
- request_time: 整個(gè)過(guò)程所消耗的時(shí)間 秒為單位
異步客戶端
class tornado.httpclient.AsyncHTTPClient
下面這段代碼和開(kāi)頭代碼的效果是一樣的
def handle_request(response):
if response.error:
print "Error:", response.error
else:
print response.body
http_client = tornado.httpclient.AsyncHTTPClient()
http_client.fetch("http://www.bilibili.com/", handle_request)
tornado.ioloop.IOLoop.instance().start()
題目之間的區(qū)別在于,前者要等待 完成整個(gè)請(qǐng)求孵坚,期間cpu是不干任何事的
而后者發(fā)出請(qǐng)求后將繼續(xù)做其他事情李皇,請(qǐng)求完成后會(huì)產(chǎn)生時(shí)間來(lái)執(zhí)行handle_request這個(gè)函數(shù)
既所謂回調(diào)函數(shù) 精算,和cpu的interrupt機(jī)制一樣蒙谓,提高效率的方法