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使用fileinput模块实现逐行读取文件的方法
Apr 29 Python
Python 多线程实例详解
Mar 25 Python
pandas DataFrame数据转为list的方法
Apr 11 Python
python主线程捕获子线程的方法
Jun 17 Python
Python面向对象程序设计示例小结
Jan 30 Python
Python获取基金网站网页内容、使用BeautifulSoup库分析html操作示例
Jun 04 Python
django框架使用方法详解
Jul 18 Python
python图的深度优先和广度优先算法实例分析
Oct 26 Python
PYTHON如何读取和写入EXCEL里面的数据
Oct 28 Python
Python使用matplotlib绘制Logistic曲线操作示例
Nov 28 Python
pytorch AvgPool2d函数使用详解
Jan 03 Python
Python如何在循环内使用list.remove()
Jun 01 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程序的php代码
2008/04/07 PHP
php实现爬取和分析知乎用户数据
2016/01/26 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
php实现的简单多进程服务器类完整示例
2020/02/01 PHP
如果文字过长,则将过长的部分变成省略号显示
2006/06/26 Javascript
Jquery 弹出层插件实现代码
2009/10/24 Javascript
JQuery读取XML文件数据并显示的实现代码
2009/12/16 Javascript
原生js做的手风琴效果的导航菜单
2013/11/08 Javascript
javascript动态向网页中添加表格实现代码
2014/02/19 Javascript
JavaScript实现简单图片翻转的方法
2015/04/17 Javascript
jQuery实现鼠标经过提示信息的地图热点效果
2015/04/26 Javascript
详解AngularJS中自定义指令的使用
2015/06/17 Javascript
JS特效实现图片自动播放并可控的效果
2015/07/31 Javascript
JS实现转动随机数抽奖特效代码
2020/04/16 Javascript
Javascript设计模式理论与编程实战之简单工厂模式
2015/11/03 Javascript
基于JS设计12306登录页面
2016/12/28 Javascript
微信小程序商品到详情的实现
2017/06/27 Javascript
javascript运行机制之执行顺序理解
2020/08/03 Javascript
[02:06]DOTA2英雄基础教程 暗影萨满
2013/12/16 DOTA
[00:38]TI珍贵瞬间系列(二):笑
2020/08/26 DOTA
在Python上基于Markov链生成伪随机文本的教程
2015/04/17 Python
python3 flask实现文件上传功能
2020/03/20 Python
Python实现分段线性插值
2018/12/17 Python
人工神经网络算法知识点总结
2019/06/11 Python
在Django中实现添加user到group并查看
2019/11/18 Python
python实现提取COCO,VOC数据集中特定的类
2020/03/10 Python
联想新加坡官方网站:Lenovo Singapore
2017/10/24 全球购物
部队领导证婚词
2014/01/12 职场文书
20年同学聚会邀请函
2014/02/04 职场文书
巾帼文明岗申报材料
2014/05/01 职场文书
医药公司开票员岗位职责
2015/04/15 职场文书
民事起诉书范本
2015/05/19 职场文书
经典爱情感言
2015/08/03 职场文书
2016年质量月活动总结报告
2016/04/05 职场文书
python元组打包和解包过程详解
2021/08/02 Python
i7 6700处理器相当于i5几代
2022/04/19 数码科技