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创建声明性迷你语言的教程
Apr 13 Python
python实现日志按天分割
Jul 22 Python
Python迷宫生成和迷宫破解算法实例
Dec 24 Python
Pycharm和Idea支持的vim插件的方法
Feb 21 Python
python函数enumerate,operator和Counter使用技巧实例小结
Feb 22 Python
Python描述符descriptor使用原理解析
Mar 21 Python
Django DRF路由与扩展功能的实现
Jun 03 Python
python文件编写好后如何实践
Jul 07 Python
Python容器类型公共方法总结
Aug 19 Python
Python内置函数及功能简介汇总
Oct 13 Python
Python3.7安装PyQt5 运行配置Pycharm的详细教程
Oct 15 Python
python中的时区问题
Jan 14 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/27 PHP
PHP简单预防sql注入的方法
2016/09/27 PHP
php实现异步将远程链接上内容(图片或内容)写到本地的方法
2016/11/30 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
phpQuery采集网页实现代码实例
2020/04/02 PHP
FF IE兼容性的修改小结
2009/09/02 Javascript
JS加jquery简单实现标签元素的显示或隐藏
2013/09/23 Javascript
node.js中的console.trace方法使用说明
2014/12/09 Javascript
JavaScript实现自动变换表格边框颜色
2015/05/08 Javascript
Underscore.js 1.3.3 中文注释翻译说明
2015/06/25 Javascript
使用jQuery mobile库检测url绝对地址和相对地址的方法
2015/12/04 Javascript
利用JavaScript判断浏览器类型及版本
2016/08/23 Javascript
jQuery图片前后对比插件beforeAfter用法示例【附demo源码下载】
2016/09/20 Javascript
JS验证图片格式和大小并预览的简单实例
2016/10/11 Javascript
js获取json中key所对应的value值的简单方法
2020/06/17 Javascript
详解JS获取HTML DOM元素的8种方法
2017/06/17 Javascript
AngularJS上传文件的示例代码
2018/11/10 Javascript
浅谈KOA2 Restful方式路由初探
2019/03/14 Javascript
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
Python标准库06之子进程 (subprocess包) 详解
2016/12/07 Python
Python中Django发送带图片和附件的邮件
2017/03/31 Python
Python编程使用NLTK进行自然语言处理详解
2017/11/16 Python
机器学习之KNN算法原理及Python实现方法详解
2018/07/09 Python
使用python对多个txt文件中的数据进行筛选的方法
2019/07/10 Python
django的ORM操作 增加和查询
2019/07/26 Python
python实现BP神经网络回归预测模型
2019/08/09 Python
基于python实现从尾到头打印链表
2019/11/02 Python
台湾租车首选品牌:IWS艾维士租车
2019/05/03 全球购物
英国家居用品和家居装饰品购物网站:Cox & Cox
2019/08/25 全球购物
美国知名的隐形眼镜电商:Contacts America
2019/11/19 全球购物
Android面试题附答案
2014/12/08 面试题
当文件系统受到破坏时,如何检查和修复系统?
2012/03/09 面试题
企业总经理职责
2014/02/02 职场文书
初三学生个人自我评定
2014/04/06 职场文书
海南召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
详解MongoDB的条件查询和排序
2021/06/23 MongoDB