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单链表的简单实现方法
Sep 23 Python
Python使用xlrd模块操作Excel数据导入的方法
May 26 Python
python文件名和文件路径操作实例
Sep 29 Python
Python进阶之递归函数的用法及其示例
Jan 31 Python
django利用request id便于定位及给日志加上request_id
Aug 26 Python
Python完成毫秒级抢淘宝大单功能
Jun 06 Python
3行Python代码实现图像照片抠图和换底色的方法
Oct 10 Python
python ubplot使用方法解析
Jan 10 Python
TensorFlow dataset.shuffle、batch、repeat的使用详解
Jan 21 Python
keras得到每层的系数方式
Jun 15 Python
使用OpenCV对车道进行实时检测的实现示例代码
Jun 19 Python
解决python对齐错误的方法
Jul 16 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
给多个地址发邮件的类
2006/10/09 PHP
ThinkPHP3.1新特性之对分组支持的改进与完善概述
2014/06/19 PHP
php递归遍历多维数组的方法
2015/04/18 PHP
PHP+MySql+jQuery实现的&quot;顶&quot;和&quot;踩&quot;投票功能
2016/05/21 PHP
PHP+redis实现的悲观锁机制示例
2018/06/12 PHP
PHP使用 Imagick 扩展实现图片合成,圆角处理功能示例
2019/09/09 PHP
php+ajax实现文件切割上传功能示例
2020/03/03 PHP
onkeypress字符按键兼容所有浏览器使用介绍
2013/04/24 Javascript
将字符串中由空格隔开的每个单词首字母大写
2014/04/06 Javascript
js实现点击后将文字或图片复制到剪贴板的方法
2014/08/04 Javascript
jquery实现textarea输入框限制字数的方法
2015/01/15 Javascript
jQuery基于json与cookie实现购物车的方法
2016/04/15 Javascript
jquery获取form表单input元素值的简单实例
2016/05/30 Javascript
Js 获取当前函数参数对象的实现代码
2016/06/20 Javascript
详解JavaScript的内置对象
2016/12/07 Javascript
谈谈JS中的!!
2017/12/07 Javascript
不到200行 JavaScript 代码实现富文本编辑器的方法
2018/01/03 Javascript
利用ECharts.js画K线图的方法示例
2018/01/10 Javascript
vue数组对象排序的实现代码
2018/06/20 Javascript
nodejs二进制与Buffer的介绍与使用
2019/07/11 NodeJs
Ant-design-vue Table组件customRow属性的使用说明
2020/10/28 Javascript
深入理解Python中的内置常量
2017/05/20 Python
Pandas DataFrame数据的更改、插入新增的列和行的方法
2019/06/25 Python
利用Python模拟登录pastebin.com的实现方法
2019/07/12 Python
在PyCharm的 Terminal(终端)切换Python版本的方法
2019/08/02 Python
Python根据指定文件生成XML的方法
2020/06/29 Python
Tensorflow--取tensorf指定列的操作方式
2020/06/30 Python
Python 使用office365邮箱的示例
2020/10/29 Python
亚历山大·王官网:Alexander Wang
2017/06/23 全球购物
几个SQL的面试题
2014/03/08 面试题
企业治理工作自我评价
2013/09/26 职场文书
房地产开发计划书
2014/01/10 职场文书
自动化专业职业生涯规划书范文
2014/01/16 职场文书
初中优秀教师事迹材料
2014/08/18 职场文书
建筑专业毕业生求职信
2014/09/30 职场文书
晶体管单管来复再生式收音机
2021/04/22 无线电