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读取ini文件、操作mysql、发送邮件实例
Jan 01 Python
Python中实现参数类型检查的简单方法
Apr 21 Python
疯狂上涨的Python 开发者应从2.x还是3.x着手?
Nov 16 Python
Python Learning 列表的更多操作及示例代码
Aug 22 Python
python实现多人聊天室
Mar 31 Python
Django框架模板注入操作示例【变量传递到模板】
Dec 19 Python
python利用tkinter实现屏保
Jul 30 Python
使用 Django Highcharts 实现数据可视化过程解析
Jul 31 Python
Python可变参数会自动填充前面的默认同名参数实例
Nov 18 Python
Numpy之将矩阵拉成向量的实例
Nov 30 Python
python3读取文件指定行的三种方法
May 24 Python
python使用torch随机初始化参数
Mar 22 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
利用PHP实现与ASP Banner组件相似的类
2006/10/09 PHP
php结合正则批量抓取网页中邮箱地址
2015/05/19 PHP
老生常谈PHP 文件写入和读取(必看篇)
2017/05/22 PHP
php实现的二叉树遍历算法示例
2017/06/15 PHP
JavaScript 学习 - 提高篇
2007/02/02 Javascript
javascript一些不错的函数脚本代码
2008/09/10 Javascript
ASP中进行HTML数据及JS数据编码函数
2009/11/11 Javascript
javascript删除字符串最后一个字符
2014/01/14 Javascript
JQuery zClip插件实现复制页面内容到剪贴板
2015/11/02 Javascript
微信小程序 WXML、WXSS 和JS介绍及详解
2016/10/08 Javascript
Canvas放置反弹效果随机图形(实例)
2017/08/17 Javascript
vue解决跨域路由冲突问题思路解析
2017/11/03 Javascript
JS常见DOM节点操作示例【创建 ,插入,删除,复制,查找】
2018/05/14 Javascript
微信小程序js文件改变参数并在视图上及时更新【推荐】
2018/06/11 Javascript
详解基于Vue2.0实现的移动端弹窗(Alert, Confirm, Toast)组件
2018/08/02 Javascript
微信小程序实现单选选项卡切换效果
2020/06/19 Javascript
微信小程序通过js实现瀑布流布局详解
2019/08/28 Javascript
微信小程序 云开发模糊查询实现解析
2019/09/02 Javascript
py2exe 编译ico图标的代码
2013/03/08 Python
深入理解Python中的内置常量
2017/05/20 Python
定制FileField中的上传文件名称实例
2017/08/23 Python
python 2.7.14安装图文教程
2018/04/08 Python
python pycurl验证basic和digest认证的方法
2018/05/02 Python
Python实现读取txt文件中的数据并绘制出图形操作示例
2019/02/26 Python
python GUI库图形界面开发之PyQt5复选框控件QCheckBox详细使用方法与实例
2020/02/28 Python
HTML5 表单验证失败的提示语问题
2017/07/13 HTML / CSS
百联网上商城:i百联
2017/01/28 全球购物
ORACLE第二个十问
2013/12/14 面试题
迅雷Cued工作心得体会
2014/01/27 职场文书
《忆江南》教学反思
2014/04/07 职场文书
公司任命书模板
2014/06/06 职场文书
讲文明懂礼貌演讲稿
2014/09/11 职场文书
垂直极限观后感
2015/06/08 职场文书
五星级酒店宣传口号
2015/12/25 职场文书
根德5570型九灯四波段立体声收音机是电子管收音机的楷模 ? 再论5570
2022/04/05 无线电
详解ZABBIX监控ESXI主机的问题
2022/06/21 Servers