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 相关文章推荐
linux系统使用python监测网络接口获取网络的输入输出
Jan 15 Python
Python读取环境变量的方法和自定义类分享
Nov 22 Python
Python脚本实现格式化css文件
Apr 08 Python
python中关于for循环的碎碎念
Jun 30 Python
Ubuntu下使用Python实现游戏制作中的切分图片功能
Mar 30 Python
Python Pandas找到缺失值的位置方法
Apr 12 Python
如何优雅地改进Django中的模板碎片缓存详解
Jul 04 Python
学习python的前途 python挣钱
Feb 27 Python
pytorch实现对输入超过三通道的数据进行训练
Jan 15 Python
pandas和spark dataframe互相转换实例详解
Feb 18 Python
python excel多行合并的方法
Dec 09 Python
Python 可视化神器Plotly详解
Dec 26 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
ThinkPHP中自定义目录结构的设置方法
2014/08/15 PHP
php中get_meta_tags()、CURL与user-agent用法分析
2014/12/16 PHP
PHP实现在线阅读PDF文件的方法
2015/06/17 PHP
关于PHP开发的9条建议
2015/07/27 PHP
php构造方法中析构方法在继承中的表现
2016/04/12 PHP
php微信公众号开发之关键词回复
2018/10/20 PHP
javascript iframe中打开文件,并检测iframe存在否
2008/12/28 Javascript
JavaScript 读取元素的CSS信息的代码
2010/02/07 Javascript
使用PHP+JQuery+Ajax分页的实现
2013/04/23 Javascript
Jquery easyui 下loaing效果示例代码
2013/08/12 Javascript
按下Enter焦点移至下一个控件的实现js代码
2013/12/11 Javascript
jquery中交替点击事件的实现代码
2014/02/14 Javascript
悬浮数字的实现案例
2014/02/19 Javascript
jQuery打印图片pdf、txt示例代码
2014/07/22 Javascript
Javascript实现获取窗口的大小和位置代码分享
2014/12/04 Javascript
使用jQuery获得内容以及内容的属性
2015/02/26 Javascript
jQuery满屏焦点图左右滚动特效代码分享
2015/09/07 Javascript
javascript实现在网页中运行本地程序的方法
2016/02/03 Javascript
jquery+ajax实现省市区三级联动 (封装和不封装两种方式)
2017/05/15 jQuery
angularJs使用$watch和$filter过滤器制作搜索筛选实例
2017/06/01 Javascript
详谈js对url进行编码和解码(三种方式的区别)
2017/08/16 Javascript
Centos7 安装Node.js10以上版本的方法步骤
2019/10/15 Javascript
JS如何把字符串转换成json
2020/02/21 Javascript
微信小程序scroll-view的滚动条设置实现
2020/03/02 Javascript
[01:06:07]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS CIS
2014/05/22 DOTA
安装Python的web.py框架并从hello world开始编程
2015/04/25 Python
python list格式数据excel导出方法
2018/10/31 Python
python缩进长度是否统一
2020/08/02 Python
python logging模块的使用详解
2020/10/23 Python
床上用品全球在线购物:BeddingInn
2016/12/18 全球购物
Rowdy Gentleman服装和配饰:美好时光
2019/09/24 全球购物
广州地球村科技数据库题目
2016/04/25 面试题
写给女朋友的道歉信
2014/01/08 职场文书
党支部综合考察材料
2014/05/19 职场文书
社区文艺活动方案
2014/08/19 职场文书
好的促销活动方案
2014/08/21 职场文书