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在windows和linux下获得本机本地ip地址方法小结
Mar 20 Python
Python实现更改图片尺寸大小的方法(基于Pillow包)
Sep 19 Python
基于python的七种经典排序算法(推荐)
Dec 08 Python
一个基于flask的web应用诞生 记录用户账户登录状态(6)
Apr 11 Python
解决python文件字符串转列表时遇到空行的问题
Jul 09 Python
Python处理CSV与List的转换方法
Apr 19 Python
实例讲解python中的序列化知识点
Oct 08 Python
python3人脸识别的两种方法
Apr 25 Python
pandas对dataFrame中某一个列的数据进行处理的方法
Jul 08 Python
tensorflow从ckpt和从.pb文件读取变量的值方式
May 26 Python
Python实现手绘图效果实例分享
Jul 22 Python
python实现自定义日志的具体方法
May 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巧获服务器端信息
2006/12/06 PHP
在PHP中使用Sockets 从Usenet中获取文件
2008/01/10 PHP
php启动时候提示PHP startup的解决方法
2013/05/07 PHP
Yii2框架引用bootstrap中日期插件yii2-date-picker的方法
2016/01/09 PHP
PHP实现防盗链的方法分析
2017/07/25 PHP
PHP高精确度运算BC函数库实例详解
2017/08/15 PHP
PHP删除数组中特定元素的两种方法
2019/02/28 PHP
浅谈PHP各环境下的伪静态配置
2019/03/13 PHP
jQuery最佳实践完整篇
2011/08/20 Javascript
js的参数有长度限制吗?发现不能超过2083个字符
2014/04/20 Javascript
js实现页面跳转重定向的几种方式
2014/05/29 Javascript
生成二维码方法汇总
2014/12/26 Javascript
JavaScript中的console.time()函数详细介绍
2014/12/29 Javascript
.NET微信公众号开发之创建自定义菜单
2015/07/16 Javascript
基于javascript实现全国省市二级联动下拉选择菜单
2016/01/28 Javascript
BootStrap glyphicons 字体图标实现方法
2016/05/01 Javascript
nodejs中安装ghost出错的原因及解决方法
2017/10/23 NodeJs
Vue.js实现分页查询功能
2020/11/15 Javascript
微信小程序云开发之云函数详解
2019/05/16 Javascript
vue2.* element tabs tab-pane 动态加载组件操作
2020/07/19 Javascript
使用Vue-scroller页面input框不能触发滑动的问题及解决方法
2020/08/08 Javascript
[45:16]完美世界DOTA2联赛循环赛 IO vs FTD BO2第二场 11.05
2020/11/06 DOTA
Python 字符串与数字输出方法
2018/07/16 Python
python中的数组赋值与拷贝的区别详解
2019/11/26 Python
pandas创建DataFrame的7种方法小结
2020/06/14 Python
python多线程和多进程关系详解
2020/12/14 Python
HTML5新增的表单元素和属性实例解析
2014/07/07 HTML / CSS
美国滑板店:Tactics
2020/11/08 全球购物
输入一行文字,找出其中大写字母、小写字母、空格、数字、及其他字符各有多少
2016/04/15 面试题
大学生表扬信范文
2014/01/09 职场文书
材料员岗位职责
2014/03/13 职场文书
宾馆仓管员岗位职责
2014/07/27 职场文书
晚会闭幕词
2015/01/28 职场文书
紧急通知
2015/04/17 职场文书
奠基仪式致辞
2015/07/30 职场文书
2019个人工作总结
2019/06/21 职场文书