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中条件选择和循环语句使用方法介绍
Mar 13 Python
python实现对一个完整url进行分割的方法
Apr 29 Python
python中随机函数random用法实例
Apr 30 Python
Python函数式编程
Jul 20 Python
python实现定时发送qq消息
Jan 18 Python
Python中调用其他程序的方式详解
Aug 06 Python
Python常用模块logging——日志输出功能(示例代码)
Nov 20 Python
Python中文分词库jieba,pkusegwg性能准确度比较
Feb 11 Python
pytorch中 gpu与gpu、gpu与cpu 在load时相互转化操作
May 25 Python
Python 用__new__方法实现单例的操作
Dec 11 Python
从Pytorch模型pth文件中读取参数成numpy矩阵的操作
Mar 04 Python
Python爬虫之爬取最新更新的小说网站
May 06 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 执行系统外部命令 system() exec() passthru()
2009/08/11 PHP
一篇有意思的技术文章php介绍篇
2010/10/26 PHP
解决File size limit exceeded 错误的方法
2013/06/14 PHP
php 实现进制相互转换
2016/04/07 PHP
PHP生成随机码的思路与方法实例探索
2019/04/11 PHP
Jquery 过滤器(first,last,not,even,odd)的使用
2014/01/22 Javascript
复制网页内容,粘贴之后自动加上网址的实现方法(脚本之家特别整理)
2014/10/16 Javascript
浅谈 javascript 事件处理
2015/01/04 Javascript
深入理解JavaScript系列(19):求值策略(Evaluation strategy)详解
2015/03/05 Javascript
基于jQuery实现美观且实用的倒计时实例代码
2015/12/30 Javascript
原生Javascript插件开发实践
2017/01/09 Javascript
JavaScript条件判断_动力节点Java学院整理
2017/06/26 Javascript
vue轮播图插件vue-awesome-swiper
2017/11/27 Javascript
vue2.0使用swiper组件实现轮播的示例代码
2018/03/03 Javascript
微信小程序自定义select下拉选项框组件的实现代码
2018/08/28 Javascript
解决Angular2 router.navigate刷新页面的问题
2018/08/31 Javascript
layer设置maxWidth及maxHeight解决方案
2019/07/26 Javascript
解决layui富文本编辑器图片上传无法回显的问题
2019/09/18 Javascript
JS中的继承操作实例总结
2020/06/06 Javascript
Python打造出适合自己的定制化Eclipse IDE
2016/03/02 Python
Python字符串格式化f-string多种功能实现
2020/05/07 Python
Django如何使用redis作为缓存
2020/05/21 Python
浅谈Python中的模块
2020/06/10 Python
Css3+Js制作漂亮时钟(附源码)
2013/04/24 HTML / CSS
详解HTML5中ol标签的用法
2015/09/08 HTML / CSS
澳大利亚排名第一的在线酒类商店:MyBottleShop
2018/04/26 全球购物
巴西服装和鞋子购物网站:Marisa
2018/10/25 全球购物
蔻驰西班牙官网:COACH西班牙
2019/01/16 全球购物
javascript实现用户必须勾选协议实例讲解
2021/03/24 Javascript
大学生优秀的自我评价分享
2013/10/22 职场文书
葛优非诚勿扰搞笑征婚台词
2014/03/17 职场文书
学校安全工作汇报材料
2014/08/16 职场文书
中学总务处工作总结
2015/08/12 职场文书
组织委员竞选稿
2015/11/21 职场文书
2016年母亲节广告语
2016/01/28 职场文书
go web 预防跨站脚本的实现方式
2021/06/11 Golang