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 相关文章推荐
利用soaplib搭建webservice详细步骤和实例代码
Nov 20 Python
分享15个最受欢迎的Python开源框架
Jul 13 Python
跟老齐学Python之深入变量和引用对象
Sep 24 Python
Python使用遗传算法解决最大流问题
Jan 29 Python
Python获取昨天、今天、明天开始、结束时间戳的方法
Jun 01 Python
一文带你了解Python中的字符串是什么
Nov 20 Python
python贪吃蛇游戏代码
Apr 18 Python
Python使用指定端口进行http请求的例子
Jul 25 Python
python编写简单端口扫描器
Sep 04 Python
python pptx复制指定页的ppt教程
Feb 14 Python
numpy库reshape用法详解
Apr 19 Python
python爬虫可以爬什么
Jun 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
解决文件名解压后乱码的问题 将文件名进行转码的代码
2012/01/10 PHP
PHP CURL获取cookies模拟登录的方法
2013/11/04 PHP
php隐藏IP地址后两位显示为星号的方法
2014/11/21 PHP
Zend Framework教程之路由功能Zend_Controller_Router详解
2016/03/07 PHP
thinkPHP框架中layer.js的封装与使用方法示例
2019/01/18 PHP
PHP实现cookie跨域session共享的方法分析
2019/08/23 PHP
Javascript代码混淆综合解决方案-Javascript在线混淆器
2006/12/18 Javascript
jQuery(1.6.3) 中css方法对浮动的实现缺陷分析
2011/09/09 Javascript
js(jQuery)获取时间的方法及常用时间类搜集
2013/10/23 Javascript
JS获取计算机mac地址以及IP的实现方法
2014/01/08 Javascript
JS+CSS实现电子商务网站导航模板效果代码
2015/09/10 Javascript
JS排序之选择排序详解
2017/04/08 Javascript
Vue原理剖析 实现双向绑定MVVM
2017/05/03 Javascript
Angular实现下载安装包的功能代码分享
2017/09/05 Javascript
详解Vue中watch的高级用法
2018/05/02 Javascript
springboot+vue实现文件上传下载
2020/11/17 Vue.js
python使用PIL缩放网络图片并保存的方法
2015/04/24 Python
Python字符串逆序的实现方法【一题多解】
2019/02/18 Python
利用python开发app实战的方法
2019/07/09 Python
python函数参数(必须参数、可变参数、关键字参数)
2019/08/16 Python
python接口自动化如何封装获取常量的类
2019/12/24 Python
对Python中 \r, \n, \r\n的彻底理解
2020/03/06 Python
使用python客户端访问impala的操作方式
2020/03/28 Python
python requests包的request()函数中的参数-params和data的区别介绍
2020/05/05 Python
详解CSS3原生支持div铺满浏览器的方法
2018/08/30 HTML / CSS
HTML5中的Web Notification桌面通知功能的实现方法
2019/07/29 HTML / CSS
阿迪达斯芬兰官方网站:adidas芬兰
2017/01/30 全球购物
一套中级Java程序员笔试题
2015/01/14 面试题
配件采购员岗位职责
2013/12/03 职场文书
《姥姥的剪纸》教学反思
2014/02/25 职场文书
行政秘书工作自我鉴定
2014/09/15 职场文书
带刀到教室的检讨书
2014/10/04 职场文书
2015年教师节慰问信
2015/03/23 职场文书
先进基层党组织事迹材料2016
2016/02/29 职场文书
python 制作一个gui界面的翻译工具
2021/05/14 Python
kubernetes集群搭建Zabbix监控平台的详细过程
2022/07/07 Servers