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批量导出导入MySQL用户的方法
Nov 15 Python
详解Python中DOM方法的动态性
Apr 11 Python
pymongo为mongodb数据库添加索引的方法
May 11 Python
在Python中执行系统命令的方法示例详解
Sep 14 Python
pyqt5自定义信号实例解析
Jan 31 Python
解决Python print输出不换行没空格的问题
Nov 14 Python
python 对多个csv文件分别进行处理的方法
Jan 07 Python
python利用tkinter实现屏保
Jul 30 Python
从pandas一个单元格的字符串中提取字符串方式
Dec 17 Python
python重要函数eval多种用法解析
Jan 14 Python
关于多元线性回归分析——Python&amp;SPSS
Feb 24 Python
Python接口自动化测试的实现
Aug 28 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+mysql写的留言本
2006/10/09 PHP
FirePHP 推荐一款PHP调试工具
2011/04/23 PHP
9个经典的PHP代码片段分享
2014/12/18 PHP
详细解读PHP的Yii框架中登陆功能的实现
2015/08/21 PHP
php使用ZipArchive函数实现文件的压缩与解压缩
2015/10/27 PHP
php 数组处理函数extract详解及实例代码
2016/11/23 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
JavaScript null和undefined区别分析
2009/10/14 Javascript
关于IE中getElementsByClassName不能用的问题解决方法
2013/08/26 Javascript
javascript检查浏览器是否支持flash的实现代码
2014/08/14 Javascript
JQuery实现动态表格点击按钮表格增加一行
2014/08/24 Javascript
jquery获取当前日期的方法
2015/01/14 Javascript
js实现可控制左右方向的无缝滚动效果
2016/05/29 Javascript
Bootstrap中定制LESS-颜色及导航条(推荐)
2016/11/21 Javascript
vue树形结构获取键值的方法示例
2018/06/21 Javascript
微信小程序学习笔记之获取位置信息操作图文详解
2019/03/29 Javascript
用webpack4开发小程序的实现方法
2019/06/04 Javascript
[03:12]完美世界DOTA2联赛PWL DAY6集锦
2020/11/05 DOTA
pyramid配置session的方法教程
2013/11/27 Python
python使用wmi模块获取windows下硬盘信息的方法
2015/05/15 Python
解决Python 遍历字典时删除元素报异常的问题
2016/09/11 Python
Python3如何解决字符编码问题详解
2017/04/23 Python
利用Pandas 创建空的DataFrame方法
2018/04/08 Python
神经网络(BP)算法Python实现及应用
2018/04/16 Python
pycharm访问mysql数据库的方法步骤
2019/06/18 Python
pyQT5 实现窗体之间传值的示例
2019/06/20 Python
基于python图像处理API的使用示例
2020/04/03 Python
Schutz鞋官方网站:Schutz Shoes
2017/12/13 全球购物
Feelunique中文官网:欧洲最大化妆品零售电商
2020/07/10 全球购物
公司聘任书模板
2014/03/29 职场文书
一分钟演讲稿
2014/04/30 职场文书
精彩的演讲稿开头
2014/05/08 职场文书
师德标兵事迹材料
2014/12/19 职场文书
预备党员自我评价范文
2015/03/04 职场文书
罗马假日观后感
2015/06/08 职场文书
Jedis操作Redis实现模拟验证码发送功能
2021/09/25 Redis