Trip 是一個(gè)協(xié)程的網(wǎng)絡(luò)庫(kù)惜辑,如 Requests 一般簡(jiǎn)單的操作,程序不再被網(wǎng)絡(luò)阻塞疫赎。
項(xiàng)目主頁(yè)見(jiàn)這里:github
兼容 Python 2.7+ 的所有版本盛撑,主流三大操作系統(tǒng)。
基于兩大依賴包:TRIP: Tornado & Requests In Pair
捧搞。
感謝Tornado與Requests讓想法可以快速變成現(xiàn)實(shí)抵卫,坦誠(chéng)的說(shuō),這個(gè)項(xiàng)目我只做了一些簡(jiǎn)單的工作胎撇。
讓協(xié)程變的簡(jiǎn)單
這是一個(gè)讓協(xié)程變的簡(jiǎn)單的項(xiàng)目陌僵,你只需要這樣:
import trip
@trip.coroutine
def main():
r = yield trip.get('https://httpbin.org/get', auth=('user', 'pass'))
print(r.content)
trip.run(main)
一百份請(qǐng)求一份時(shí)間
基于 Tornado 的協(xié)程讓網(wǎng)絡(luò)阻塞不再成為問(wèn)題:(這里演示兼容用法)
import time, functools
import requests, trip
def timeit(fn):
start_time = time.time()
fn()
return time.time() - start_time
url = 'http://httpbin.org/get'
times = 10 # 100 changed for inland network delay
def fetch():
r = [requests.get(url) for i in range(times)]
return r
@trip.coroutine
def async_fetch():
r = yield [trip.get(url) for i in range(times)]
raise trip.Return(r)
print('Non-trip cost: %ss' % timeit(fetch))
print('Trip cost: %ss' % timeit(functools.partial(trip.run, async_fetch)))
# Result:
# Non-trip cost: 17.90799999237s
# Trip cost: 0.172300004959s
由于協(xié)程的特性,所有的等待時(shí)間重合在了一起创坞。
你不需要每個(gè)請(qǐng)求開(kāi)一個(gè)線程碗短,主線程中一切也可以井然有序的進(jìn)行。
可以想象如果你在寫(xiě)一個(gè)爬蟲(chóng)题涨,這將節(jié)省多少時(shí)間偎谁!
讓協(xié)程服務(wù)人類
基于 Requests 的操作方式讓協(xié)程 HTTP 從未如此簡(jiǎn)單:(這里使用 Python3 演示async/await)
>>> async def main():
... global r
... r = await trip.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))
...
>>> trip.run(main)
>>> r.status_code
200
>>> r.headers['content-type']
'application/json'
>>> r.encoding
None
>>> r.text
u'{"authenticated": true,...'
>>> r.json()
{u'authenticated': True, u'user': u'user'}
只要你有一些 Requests 基礎(chǔ)就可以輕松使用 Trip,協(xié)程不再遙不可及纲堵。
重現(xiàn)了幾乎所有 Requests 的操作巡雨,最大限度的減少了你的學(xué)習(xí)成本。
以一個(gè)爬蟲(chóng)為例
為了不打擾正常網(wǎng)站的運(yùn)行席函,這里以httpbin.org
作為目標(biāo)網(wǎng)站铐望。
設(shè)置 Cookies 模擬登陸,get 請(qǐng)求模擬爬取內(nèi)容茂附。
那么普通 Requests 是這樣的:
import requests
url = 'http://httpbin.org'
s = requests.Session()
def fetch(times=10):
s.get('%s/cookies/set?name=value' % url)
r = [s.get('%s/get' % url) for i in range(times)]
print r
fetch()
使用 Trip 以后就會(huì)變成這樣:
import trip
url = 'http://httpbin.org'
s = trip.Session()
@trip.coroutine
def fetch(times=10):
yield s.get('%s/cookies/set?name=value' % url)
r = yield [s.get('%s/get' % url) for i in range(times)]
print r
trip.run(fetch)
幾乎不需要修改代碼正蛙,爬蟲(chóng)就獲得了協(xié)程的特性!
最后
爬蟲(chóng)耗時(shí)太久優(yōu)化困難嗎营曼?
各種協(xié)程網(wǎng)絡(luò)框架難以使用嗎乒验?
大型爬蟲(chóng)框架臃腫無(wú)法靈活定制嗎?
試試Trip蒂阱,你不會(huì)后悔的锻全!