python实现多线程网页下载器


Posted in Python onApril 15, 2018

本文为大家分享了python实现的一个多线程网页下载器,供大家参考,具体内容如下

这是一个有着真实需求的实现,我的用途是拿它来通过 HTTP 方式向服务器提交游戏数据。把它放上来也是想大家帮忙挑刺,找找 bug,让它工作得更好。

keywords:python,http,multi-threads,thread,threading,httplib,urllib,urllib2,Queue,http pool,httppool

废话少说,上源码:

# -*- 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)

 有兴趣想尝试运行的朋友,可以把它保存为 xxxx.py,然后执行 python xxxx.py 10 4,其中 10 表示向 google.cn 请求 10 次查询,4 表示由 4 条线程来执行这些任务。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
详解在Python的Django框架中创建模板库的方法
Jul 20 Python
Python3实现发送QQ邮件功能(文本)
Dec 15 Python
Python中pow()和math.pow()函数用法示例
Feb 11 Python
对Python中的@classmethod用法详解
Apr 21 Python
python通过Windows下远程控制Linux系统
Jun 20 Python
Python操作Excel插入删除行的方法
Dec 10 Python
python3.7 sys模块的具体使用
Jul 22 Python
django 通过URL访问上传的文件方法
Jul 28 Python
Python imutils 填充图片周边为黑色的实现
Jan 19 Python
如何基于Python pygame实现动画跑马灯
Nov 18 Python
python爬取豆瓣电影TOP250数据
May 23 Python
忆童年!用Python实现愤怒的小鸟游戏
Jun 07 Python
Python实现定时精度可调节的定时器
Apr 15 #Python
Python编写一个优美的下载器
Apr 15 #Python
python实现音乐下载器
Apr 15 #Python
tensorflow 1.0用CNN进行图像分类
Apr 15 #Python
tensorflow学习笔记之mnist的卷积神经网络实例
Apr 15 #Python
tensorflow学习笔记之简单的神经网络训练和测试
Apr 15 #Python
Pytorch入门之mnist分类实例
Apr 14 #Python
You might like
删除无限级目录与文件代码共享
2006/07/12 PHP
windows下配置php5.5开发环境及开发扩展
2014/12/25 PHP
Laravel框架查询构造器简单示例
2019/05/08 PHP
用JS实现的一个include函数
2007/07/21 Javascript
javascript 鼠标悬浮图片显示原图 移出鼠标后原图消失(多图)
2009/12/28 Javascript
JQuery 构建客户/服务分离的链接模型中Table中的排序分析
2010/01/22 Javascript
文本框获得焦点和失去焦点的判断代码
2012/03/18 Javascript
Javascript面向对象扩展库代码分享
2012/03/27 Javascript
网页右键ie不支持event.preventDefault和event.returnValue (需要加window)
2013/02/22 Javascript
js showModalDialog参数的使用详解
2014/01/07 Javascript
JS修改地址栏参数实例代码
2016/06/14 Javascript
基于JS实现导航条flash导航条
2016/06/17 Javascript
Javascript之深入浅出prototype
2017/02/06 Javascript
基于iScroll实现下拉刷新和上滑加载效果
2017/07/18 Javascript
基于 Vue.js 之 iView UI 框架非工程化实践记录(推荐)
2017/11/21 Javascript
基于Swiper实现移动端页面图片轮播效果
2017/12/28 Javascript
基于Vuejs的搜索匹配功能实现方法
2018/03/03 Javascript
微信小程序将字符串生成二维码图片的操作方法
2018/07/17 Javascript
vue实现购物车抛物线小球动画效果的方法详解
2019/02/13 Javascript
vue页面切换项目实现转场动画的方法
2019/11/12 Javascript
create-react-app中添加less支持的实现
2019/11/15 Javascript
基于JavaScript实现十五拼图代码实例
2020/04/26 Javascript
[03:19]2016国际邀请赛中国区预选赛第四日TOP10镜头集锦
2016/07/01 DOTA
总结Python中逻辑运算符的使用
2015/05/13 Python
Python文本特征抽取与向量化算法学习
2017/12/22 Python
python3中zip()函数使用详解
2018/06/29 Python
使用批处理脚本自动生成并上传NuGet包(操作方法)
2019/11/19 Python
美国知名户外用品畅销中心:Sierra Trading Post
2016/07/19 全球购物
OSPREY LONDON官网:英国本土皮具品牌
2019/05/31 全球购物
大学生就业自荐信
2013/10/26 职场文书
银行实习生的自我评价
2014/01/13 职场文书
餐厅总厨求职信
2014/03/04 职场文书
业务内勤岗位职责
2014/04/30 职场文书
课堂打架检讨书200字
2014/11/21 职场文书
幼儿园六一儿童节主持词
2015/06/30 职场文书
幼儿园教师管理制度
2015/08/05 职场文书