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代码制作configure文件示例
Jul 28 Python
python实现获取客户机上指定文件并传输到服务器的方法
Mar 16 Python
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
Feb 23 Python
python 根据时间来生成唯一的字符串方法
Jan 14 Python
在Pycharm中执行scrapy命令的方法
Jan 16 Python
python 通过可变参数计算n个数的乘积方法
Jun 13 Python
Python读取xlsx文件的实现方法
Jul 04 Python
Django ORM多对多查询方法(自定义第三张表&amp;ManyToManyField)
Aug 09 Python
扩展Django admin的list_filter()可使用范围方法
Aug 21 Python
Pycharm中配置远程Docker运行环境的教程图解
Jun 11 Python
python调用百度AI接口实现人流量统计
Feb 03 Python
Python如何快速找到多个字典中的公共键(key)
Apr 29 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
WordPress判断用户是否登录的代码
2011/03/17 PHP
PHP连接MySQL查询结果中文显示乱码解决方法
2013/10/25 PHP
php中3种方法删除字符串中间的空格
2014/03/10 PHP
CI框架入门示例之数据库取数据完整实现方法
2014/11/05 PHP
IE DOM实现存在的部分问题及解决方法
2009/07/25 Javascript
模拟多级复选框效果的jquery代码
2013/08/13 Javascript
原生javascript实现无间缝滚动示例
2014/01/28 Javascript
javascript里使用php代码实例
2014/12/13 Javascript
基于Bootstrap+jQuery.validate实现Form表单验证
2014/12/16 Javascript
JS与jQ读取xml文件的方法
2015/12/08 Javascript
AngularJS ng-repeat指令中使用track by子语句解决重复数据遍历错误问题
2017/01/21 Javascript
Vue2递归组件实现树形菜单
2017/04/10 Javascript
微信小程序 共用变量值的实现
2017/07/12 Javascript
Node.js简单入门前传
2017/08/21 Javascript
温故知新——JavaScript中的字符串连接问题最全总结(推荐)
2017/08/21 Javascript
JS实现定时任务每隔N秒请求后台setInterval定时和ajax请求问题
2017/10/15 Javascript
深度了解vue.js中hooks的相关知识
2019/06/14 Javascript
送你43道JS面试题(收藏)
2019/06/17 Javascript
jQuery实现中奖播报功能(让文本滚动起来) 简单设置数值即可
2020/03/20 jQuery
使用element-ui +Vue 解决 table 里包含表单验证的问题
2020/07/17 Javascript
vue实现标签云效果的示例
2020/11/09 Javascript
教你如何在Django 1.6中正确使用 Signal
2014/06/22 Python
Python HTML解析器BeautifulSoup用法实例详解【爬虫解析器】
2019/04/05 Python
wxPython实现整点报时
2019/11/18 Python
Python3并发写文件与Python对比
2019/11/20 Python
新手学习Python2和Python3中print不同的用法
2020/06/09 Python
Python requests HTTP验证登录实现流程
2020/11/05 Python
通过实例解析python and和or使用方法
2020/11/14 Python
Hanro官网:奢华男士和女士内衣、睡衣和家居服
2018/10/25 全球购物
瑞士图书网站:Weltbild.ch
2019/09/17 全球购物
在子网210.27.48.21/30种有多少个可用地址?分别是什么?
2014/07/27 面试题
项目合作协议书范本
2014/04/16 职场文书
党员三严三实对照检查材料
2014/10/13 职场文书
服务承诺书
2015/01/19 职场文书
2015年测量员工作总结
2015/05/23 职场文书
利用python Pandas实现批量拆分Excel与合并Excel
2021/05/23 Python