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天气预报采集器实现代码(网页爬虫)
Oct 07 Python
实例解析Python设计模式编程之桥接模式的运用
Mar 02 Python
Python中单、双下划线的区别总结
Dec 01 Python
Python RabbitMQ消息队列实现rpc
May 30 Python
python 美化输出信息的实例
Oct 15 Python
Python画图高斯分布的示例
Jul 10 Python
python代码实现逻辑回归logistic原理
Aug 07 Python
Python使用mongodb保存爬取豆瓣电影的数据过程解析
Aug 14 Python
tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式
Jan 23 Python
python GUI库图形界面开发之PyQt5浏览器控件QWebEngineView详细使用方法
Feb 26 Python
PyTorch之nn.ReLU与F.ReLU的区别介绍
Jun 27 Python
django使用多个数据库的方法实例
Mar 04 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 array_unique之后json_encode需要注意
2011/01/02 PHP
用PHP写的基于Memcache的Queue实现代码
2011/11/27 PHP
php获取服务器操作系统相关信息的方法
2016/10/08 PHP
基于laravel belongsTo使用详解
2019/10/18 PHP
Laravel 中使用简单的方法跟踪用户是否在线(推荐)
2019/10/30 PHP
[原创]站长必须要知道的javascript广告代码
2007/05/30 Javascript
jQuery 开发者应该注意的9个错误
2012/05/03 Javascript
jquery 表格的增行删行实现思路
2013/03/21 Javascript
js 得到文件后缀(通过正则实现)
2013/07/08 Javascript
javascript使用正则控制input输入框允许输入的值方法大全
2014/06/19 Javascript
JavaScript获取鼠标移动时的坐标(兼容IE8、chome谷歌、Firefox)
2014/09/13 Javascript
基于jQuery Tipso插件实现消息提示框特效
2016/03/16 Javascript
基于jquery编写的放大镜插件
2016/03/23 Javascript
angularJS Provider、factory、service详解及实例代码
2016/09/21 Javascript
ES6学习教程之模板字符串详解
2017/10/09 Javascript
判断jQuery是否加载完成,没完成继续判断的解决方法
2017/12/06 jQuery
微信小程序select下拉框实现源码
2019/11/08 Javascript
html中创建并调用vue组件的几种方法汇总
2020/11/17 Javascript
python3新特性函数注释Function Annotations用法分析
2016/07/28 Python
Python内置模块ConfigParser实现配置读写功能的方法
2018/02/12 Python
pandas 快速处理 date_time 日期格式方法
2018/11/12 Python
python3爬虫怎样构建请求header
2018/12/23 Python
pytorch 在网络中添加可训练参数,修改预训练权重文件的方法
2019/08/17 Python
Python 继承,重写,super()调用父类方法操作示例
2019/09/29 Python
python中栈的原理及实现方法示例
2019/11/27 Python
python 实现从高分辨图像上抠取图像块
2020/01/02 Python
django 利用Q对象与F对象进行查询的实现
2020/05/15 Python
python中if嵌套命令实例讲解
2021/02/25 Python
浅谈h5自定义audio(问题及解决)
2016/08/19 HTML / CSS
国际奢侈品品牌童装购物网站:Designer Childrenswear
2019/05/08 全球购物
女儿十岁生日答谢词
2014/01/27 职场文书
计划生育诚信协议书
2014/11/02 职场文书
幼儿园园长新年寄语2015
2014/12/08 职场文书
美甲店的创业计划书模板
2019/08/23 职场文书
Django框架模板用法详解
2022/06/10 Python
python 镜像环境搭建总结
2022/09/23 Python