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抓taobao图片爬虫
Oct 26 Python
详解Python中with语句的用法
Apr 15 Python
python操作sqlite的CRUD实例分析
May 08 Python
python和opencv实现抠图
Jul 18 Python
Flask框架WTForm表单用法示例
Jul 20 Python
Python常见MongoDB数据库操作实例总结
Jul 24 Python
Django forms组件的使用教程
Oct 08 Python
pygame实现俄罗斯方块游戏(对战篇1)
Oct 29 Python
pytorch masked_fill报错的解决
Feb 18 Python
关于win10在tensorflow的安装及在pycharm中运行步骤详解
Mar 16 Python
pytorch简介
Nov 11 Python
python excel和yaml文件的读取封装
Jan 12 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对gzip文件或者字符串解压实例参考
2008/07/25 PHP
PHP5中GD库生成图形验证码(有汉字)
2013/07/28 PHP
php中的filesystem文件系统函数介绍及使用示例
2014/02/13 PHP
微信随机生成红包金额算法php版
2016/07/21 PHP
PHP 扩展Memcached命令用法实例总结
2020/06/04 PHP
解决IE下select标签innerHTML插入option的BUG(兼容IE,FF,Opera,Chrome,Safari)
2010/05/13 Javascript
LazyLoad 延迟加载(按需加载)
2010/05/31 Javascript
Jquery submit()无法提交问题
2013/04/21 Javascript
JQuery拖动表头边框线调整表格列宽效果代码
2014/09/10 Javascript
JavaScript中Number.MIN_VALUE属性的使用示例
2015/06/04 Javascript
jQuery实现对无序列表的排序功能(附demo源码下载)
2016/06/25 Javascript
深入浅析var,let,const的异同点
2018/08/07 Javascript
解决vue中虚拟dom,无法实时更新的问题
2018/09/15 Javascript
Vuejs+vue-router打包+Nginx配置的实例
2018/09/20 Javascript
vue router导航守卫(router.beforeEach())的使用详解
2019/04/19 Javascript
vue项目创建步骤及路由router
2020/01/14 Javascript
[00:37]食人魔魔法师轮盘吉兆顺应全新至宝将拥有额外款式
2019/12/19 DOTA
python爬取网站数据保存使用的方法
2013/11/20 Python
跟老齐学Python之玩转字符串(3)
2014/09/14 Python
python中文编码问题小结
2014/09/28 Python
解决Python一行输出不显示的问题
2018/12/03 Python
Django集成celery发送异步邮件实例
2019/12/17 Python
Django用户身份验证完成示例代码
2020/04/03 Python
Python远程方法调用实现过程解析
2020/07/28 Python
Python3.7安装PyQt5 运行配置Pycharm的详细教程
2020/10/15 Python
Python爬虫简单运用爬取代理IP的实现
2020/12/01 Python
森海塞尔美国官网:Sennheiser耳机与耳麦
2017/07/19 全球购物
Rag & Bone官网:瑞格布恩高级成衣
2018/04/19 全球购物
实现strstr功能,即在父串中寻找子串首次出现的位置
2016/08/05 面试题
高校毕业生登记表自我鉴定
2013/11/03 职场文书
研究生毕业自我鉴定范文
2014/03/27 职场文书
小学生中国梦演讲稿
2014/04/23 职场文书
技术岗位竞聘演讲稿
2014/05/16 职场文书
2014新生大学四年计划书
2014/09/21 职场文书
小学家长通知书评语
2014/12/31 职场文书
承诺函格式模板
2015/01/21 职场文书