0

有沒有一種可能的方式來加速我的代碼使用多處理接口?問題是這個接口使用map函數,它只與1個函數一起工作。但我的代碼有3個功能。我試圖將我的功能合併爲一個,但沒有取得成功。我的腳本從文件讀取站點的URL,並對其執行3個功能。 For循環使得它很慢,因爲我得到了很多的URLPython請求模塊多線程

import requests 

def Login(url): #Log in  
    payload = { 
     'UserName_Text'  : 'user', 
     'UserPW_Password' : 'pass', 
     'submit_ButtonOK' : 'return buttonClick;' 
     } 

    try: 
     p = session.post(url+'/login.jsp', data = payload, timeout=10) 
    except (requests.exceptions.ConnectionError, requests.exceptions.Timeout): 
     print "site is DOWN! :", url[8:] 
     session.cookies.clear() 
     session.close() 
    else: 
     print 'OK: ', p.url 

def Timer(url): #Measure request time 
    try: 
     timer = requests.get(url+'/login.jsp').elapsed.total_seconds() 
    except (requests.exceptions.ConnectionError): 
     print 'Request time: None' 
     print '-----------------------------------------------------------------' 
    else: 
     print 'Request time:', round(timer, 2), 'sec' 

def Logout(url): # Log out 
    try: 
     logout = requests.get(url+'/logout.jsp', params={'submit_ButtonOK' : 'true'}, cookies = session.cookies) 
    except(requests.exceptions.ConnectionError): 
     pass 
    else: 
     print 'Logout '#, logout.url 
     print '-----------------------------------------------------------------' 
     session.cookies.clear() 
     session.close() 
for line in open('text.txt').read().splitlines(): 
    session = requests.session() 
    Login(line) 
    Timer(line) 
    Logout(line) 

回答

0

有很多方法來完成你的任務,但不需要在該級別多,它只是增加了複雜性,恕我直言

請看看gevent,greenlets和monkey patching,取而代之!

一旦你的代碼準備好了,你可以將一個主函數包裝到一個gevent循環中,如果你應用了猴子補丁,gevent框架將同時運行N個作業(你可以創建一個作業池,設置併發限制等)

這個例子應該有所幫助:

#!/usr/bin/python 
# Copyright (c) 2009 Denis Bilenko. See LICENSE for details. 

"""Spawn multiple workers and wait for them to complete""" 
from __future__ import print_function 
import sys 

urls = ['http://www.google.com', 'http://www.yandex.ru', 'http://www.python.org'] 

import gevent 
from gevent import monkey 

# patches stdlib (including socket and ssl modules) to cooperate with other greenlets 
monkey.patch_all() 


if sys.version_info[0] == 3: 
    from urllib.request import urlopen 
else: 
    from urllib2 import urlopen 


def print_head(url): 
    print('Starting %s' % url) 
    data = urlopen(url).read() 
    print('%s: %s bytes: %r' % (url, len(data), data[:50])) 

jobs = [gevent.spawn(print_head, url) for url in urls] 

gevent.wait(jobs) 

你可以找到更多here並在Github repository,從那裏這個例子來自

PS Greenlet也可以處理請求,你不需要改變你的代碼。

+0

所以多處理是複雜的,但gevent不是? OK :) – Messa 2015-02-08 12:06:37

+0

Imho是的,當我沒有意識到很多事情時,我發現很容易理解gevent,而不是多處理池管理。Gevent爲我完成了大部分工作,但僅僅是個人觀點:-) – user3699166 2015-02-08 12:09:17

+0

您確定'gevent'與'requests'庫兼容嗎?我記得至少有一些過去的'請求'版本無法像'gevent'一樣工作。 – jfs 2015-02-08 17:03:20

4

是的,你可以使用多處理。

from multiprocessing import Pool 

def f(line): 
    session = requests.session() 
    Login(session, line) 
    Timer(session, line) 
    Logout(session, line)   

if __name__ == '__main__': 
    urls = open('text.txt').read().splitlines() 
    p = Pool(5) 
    print(p.map(f, urls)) 

的請求session不能全局和工人之間共享,每一個工人都應該使用它自己的會話。

你寫道,你已經「試圖將我的功能合併成一個,但沒有取得成功」。什麼沒有工作?

+0

那麼,你在你的例子中做了這個更優雅。 – 2015-02-08 12:19:39

+0

我的腳本陷入了困境。那麼,我應該如何在代碼中插入'[...]'? 這不起作用: 線路開放( '的text.txt')閱讀()splitlines(): \t打印p.map(F,線) – 2015-02-08 12:44:39

+0

地圖()不能與工作循環 – 2015-02-08 13:08:01