python實(shí)現(xiàn)多線程網(wǎng)頁(yè)下載器
本文為大家分享了python實(shí)現(xiàn)的一個(gè)多線程網(wǎng)頁(yè)下載器,供大家參考,具體內(nèi)容如下
這是一個(gè)有著真實(shí)需求的實(shí)現(xiàn),我的用途是拿它來(lái)通過(guò) HTTP 方式向服務(wù)器提交游戲數(shù)據(jù)。把它放上來(lái)也是想大家?guī)兔μ舸蹋艺?bug,讓它工作得更好。
keywords:python,http,multi-threads,thread,threading,httplib,urllib,urllib2,Queue,http pool,httppool
廢話少說(shuō),上源碼:
# -*- coding:utf-8 -*-
import urllib, httplib
import thread
import time
from Queue import Queue, Empty, Full
HEADERS = {"Content-type": "application/x-www-form-urlencoded",
'Accept-Language':'zh-cn',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.0)',
"Accept": "text/plain"}
UNEXPECTED_ERROR = -1
POST = 'POST'
GET = 'GET'
def base_log(msg):
print msg
def base_fail_op(task, status, log):
log('fail op. task = %s, status = %d'%(str(task), status))
def get_remote_data(tasks, results, fail_op = base_fail_op, log = base_log):
while True:
task = tasks.get()
try:
tid = task['id']
hpt = task['conn_args'] # hpt <= host:port, timeout
except KeyError, e:
log(str(e))
continue
log('thread_%s doing task %d'%(thread.get_ident(), tid))
#log('hpt = ' + str(hpt))
conn = httplib.HTTPConnection(**hpt)
try:
params = task['params']
except KeyError, e:
params = {}
params = urllib.urlencode(params)
#log('params = ' + params)
try:
method = task['method']
except KeyError:
method = 'GET'
#log('method = ' + method)
try:
url = task['url']
except KeyError:
url = '/'
#log('url = ' + url)
headers = HEADERS
try:
tmp = task['headers']
except KeyError, e:
tmp = {}
headers.update(tmp)
#log('headers = ' + str(headers))
headers['Content-Length'] = len(params)
try:
if method == POST:
conn.request(method, url, params, headers)
else:
conn.request(method, url + params)
response = conn.getresponse()
except Exception, e:
log('request failed. method = %s, url = %s, params = %s headers = %s'%(
method, url, params, headers))
log(str(e))
fail_op(task, UNEXPECTED_ERROR, log)
continue
if response.status != httplib.OK:
fail_op(task, response.status, log)
continue
data = response.read()
results.put((tid, data), True)
class HttpPool(object):
def __init__(self, threads_count, fail_op, log):
self._tasks = Queue()
self._results = Queue()
for i in xrange(threads_count):
thread.start_new_thread(get_remote_data,
(self._tasks, self._results, fail_op, log))
def add_task(self, tid, host, url, params, headers = {}, method = 'GET', timeout = None):
task = {
'id' : tid,
'conn_args' : {'host' : host} if timeout is None else {'host' : host, 'timeout' : timeout},
'headers' : headers,
'url' : url,
'params' : params,
'method' : method,
}
try:
self._tasks.put_nowait(task)
except Full:
return False
return True
def get_results(self):
results = []
while True:
try:
res = self._results.get_nowait()
except Empty:
break
results.append(res)
return results
def test_google(task_count, threads_count):
hp = HttpPool(threads_count, base_fail_op, base_log)
for i in xrange(task_count):
if hp.add_task(i,
'www.google.cn',
'/search?',
{'q' : 'lai'},
# method = 'POST'
):
print 'add task successed.'
while True:
results = hp.get_results()
if not results:
time.sleep(1.0 * random.random())
for i in results:
print i[0], len(i[1])
# print unicode(i[1], 'gb18030')
if __name__ == '__main__':
import sys, random
task_count, threads_count = int(sys.argv[1]), int(sys.argv[2])
test_google(task_count, threads_count)
有興趣想嘗試運(yùn)行的朋友,可以把它保存為 xxxx.py,然后執(zhí)行 python xxxx.py 10 4,其中 10 表示向 google.cn 請(qǐng)求 10 次查詢,4 表示由 4 條線程來(lái)執(zhí)行這些任務(wù)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Python中math和decimal模塊的解析與實(shí)踐
在Python中,math?和?decimal?模塊是處理數(shù)學(xué)運(yùn)算的重要工具,本文將深入探討這兩個(gè)模塊的基礎(chǔ)知識(shí),并通過(guò)實(shí)際的代碼示例演示它們的用法,希望對(duì)大家有所幫助2024-02-02
Python+Pyecharts實(shí)現(xiàn)散點(diǎn)圖的繪制
散點(diǎn)圖是指在回歸分析中,數(shù)據(jù)點(diǎn)在直角坐標(biāo)系平面上的分布圖,散點(diǎn)圖表示因變量隨自變量而變化的大致趨勢(shì),據(jù)此可以選擇合適的函數(shù)對(duì)數(shù)據(jù)點(diǎn)進(jìn)行擬合。本文將利用Python Pyecharts實(shí)現(xiàn)散點(diǎn)圖的繪制,需要的可以參考一下2022-06-06
python操作excel的包(openpyxl、xlsxwriter)
這篇文章主要為大家詳細(xì)介紹了python操作excel的包,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
Python中類(lèi)型關(guān)系和繼承關(guān)系實(shí)例詳解
這篇文章主要介紹了Python中類(lèi)型關(guān)系和繼承關(guān)系,較為詳細(xì)的分析了Python中類(lèi)型關(guān)系和繼承關(guān)系的原理與使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-05-05
Python利用 SVM 算法實(shí)現(xiàn)識(shí)別手寫(xiě)數(shù)字
支持向量機(jī) (Support Vector Machine, SVM) 是一種監(jiān)督學(xué)習(xí)技術(shù),它通過(guò)根據(jù)指定的類(lèi)對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行最佳分離,從而在高維空間中構(gòu)建一個(gè)或一組超平面。本文將介紹通過(guò)SVM算法實(shí)現(xiàn)手寫(xiě)數(shù)字的識(shí)別,需要的可以了解一下2021-12-12
python3+pyqt5+itchat微信定時(shí)發(fā)送消息的方法
今天小編就為大家分享一篇python3+pyqt5+itchat微信定時(shí)發(fā)送消息的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
python 裝飾器帶參數(shù)和不帶參數(shù)步驟詳解
裝飾器是Python語(yǔ)言中一種特殊的語(yǔ)法,用于在不修改原函數(shù)代碼的情況下,為函數(shù)添加額外的功能或修改函數(shù)的行為,這篇文章主要介紹了python裝飾器帶參數(shù)和不帶參數(shù)的相關(guān)知識(shí),需要的朋友可以參考下2024-05-05
在anaconda中配置graphviz包的詳細(xì)過(guò)程
graphviz是貝爾實(shí)驗(yàn)室開(kāi)發(fā)的一個(gè)開(kāi)源的工具包,它使用一個(gè)特定的DSL(領(lǐng)域特定語(yǔ)言):dot作為腳本語(yǔ)言,然后使用布局引擎來(lái)解析此腳本,并完成自動(dòng)布局,這篇文章主要介紹了如何在anaconda中配置graphviz包,需要的朋友可以參考下2023-02-02
OpenCV實(shí)戰(zhàn)之OpenCV中的顏色空間
這篇文章主要介紹了OpenCV實(shí)戰(zhàn)之OpenCV中的顏色空間,解計(jì)算機(jī)視覺(jué)中常用的色彩空間,并將其用于基于顏色分割。我們還將用C?++和Python共享演示代碼,下文詳細(xì)內(nèi)容需要的小伙伴可以參考一下2022-04-04

