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 相关文章推荐
Python3 能振兴 Python的原因分析
Nov 28 Python
python使用Tkinter显示网络图片的方法
Apr 24 Python
python计算一个序列的平均值的方法
Jul 11 Python
玩转python爬虫之cookie使用方法
Feb 17 Python
对python 矩阵转置transpose的实例讲解
Apr 17 Python
python执行系统命令后获取返回值的几种方式集合
May 12 Python
Python3内置模块random随机方法小结
Jul 13 Python
Python 生成一个从0到n个数字的列表4种方法小结
Nov 28 Python
Python 剪绳子的多种思路实现(动态规划和贪心)
Feb 24 Python
解决安装新版PyQt5、PyQT5-tool后打不开并Designer.exe提示no Qt platform plugin的问题
Apr 24 Python
python实现文法左递归的消除方法
May 22 Python
Pytorch使用PIL和Numpy将单张图片转为Pytorch张量方式
May 25 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不用正则采集速度探究总结
2008/03/24 PHP
深入理解用mysql_fetch_row()以数组的形式返回查询结果
2013/06/05 PHP
PHP调用wsdl文件类型的接口代码分享
2014/11/19 PHP
Gird事件机制初级读本
2007/03/10 Javascript
javascipt匹配单行和多行注释的正则表达式
2013/11/20 Javascript
利用javascript实现禁用网页上所有文本框,下拉菜单,多行文本域
2013/12/14 Javascript
通过复制Table生成word和excel的javascript代码
2014/01/20 Javascript
Asp.Net alert弹出提示信息的几种方法总结
2014/01/29 Javascript
JS常用函数使用指南
2014/11/23 Javascript
jQuery多个input求和的实现方法
2015/02/12 Javascript
JS显示表格内指定行html代码的方法
2015/03/31 Javascript
浅谈jquery事件处理
2015/04/24 Javascript
javascript从作用域链谈闭包
2020/07/29 Javascript
JavaScript操作表单实例讲解(上)
2016/06/20 Javascript
JavaScript面向对象编写购物车功能
2016/08/19 Javascript
详解vue-router基本使用
2017/04/18 Javascript
Node.JS 循环递归复制文件夹目录及其子文件夹下的所有文件
2017/09/18 Javascript
vue生命周期的探索
2019/04/03 Javascript
[01:02]DOTA2上海特锦赛SHOWOPEN
2016/03/25 DOTA
[01:15]PWL S2开团时刻第二期——他们杀 我就白给
2020/11/25 DOTA
python赋值操作方法分享
2013/03/23 Python
Python脚本实现下载合并SAE日志
2015/02/10 Python
详解Python Qt的窗体开发的基本操作
2019/07/14 Python
为什么说Python可以实现所有的算法
2019/10/04 Python
Keras实现DenseNet结构操作
2020/07/06 Python
修复iPhone的safari浏览器上submit按钮圆角bug
2012/12/24 HTML / CSS
Stubhub英国:购买体育、演唱会和剧院门票
2018/06/10 全球购物
兰兰过桥教学反思
2014/02/08 职场文书
《月迹》教学反思
2014/02/19 职场文书
人事专员岗位说明书
2014/07/29 职场文书
党员个人剖析材料
2014/09/30 职场文书
幼儿园六一儿童节活动总结
2015/02/10 职场文书
2015年大学班长个人工作总结
2015/04/24 职场文书
react中props 的使用及进行限制的方法
2021/04/28 Javascript
Python采集爬取京东商品信息和评论并存入MySQL
2022/04/12 Python
人工智能深度学习OpenAI baselines的使用方法
2022/05/20 Python