下载1000次网页资源

1,普通循环方式下载1000次,非常慢

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import os
import time
import urllib
import urllib2 total_times = 1000 def worker(url):
try:
f = urllib2.urlopen(url,timeout=10800)
body = f.read()
except:
print sys.exc_info()
return 0
return 1 if __name__ == "__main__": for i in range(total_times):
url = "http://web.kuaipan.cn/static/images/pc.png"
worker(url) #root:~/test # time ./c.py
#real 4m6.700s
#user 0m1.192s
#sys 0m1.736s

2,使用进程池下载,有点慢

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import os
import time
import urllib
import urllib2
import multiprocessing total_times = 1000 def worker(url):
try:
f = urllib2.urlopen(url,timeout=10800)
body = f.read()
except:
print sys.exc_info()
return 0
return 1 if __name__ == "__main__": pool_size = multiprocessing.cpu_count() * 2
pool = multiprocessing.Pool(processes=pool_size) for i in range(total_times):
url = "http://web.kuaipan.cn/static/images/pc.png"
pool.apply_async(worker, (url,)) pool.close()
pool.join() #root:~/test # time ./pc.py
#real 1m43.668s
#user 0m1.480s
#sys 0m1.628s

3,使用twisted网络库,同样发起1000次请求,耗时减少为15s左右,性能提升很多,很快

#!/usr/bin/python

from sys import argv
from pprint import pformat #from twisted.internet.task import react
from twisted.internet import reactor
from twisted.web.client import Agent, readBody
from twisted.web.http_headers import Headers total_times = 1000
times = 0 def cbRequest(response):
#print 'Response version:', response.version
#print 'Response code:', response.code
#print 'Response phrase:', response.phrase
#print 'Response headers:'
#print pformat(list(response.headers.getAllRawHeaders()))
d = readBody(response)
d.addCallback(cbBody)
return d def cbBody(body):
#print 'Response body:'
#print body
data = body def cbShutdown(ignored):
global times
times = times + 1
if total_times - 1 < times:
reactor.stop() def curl(url):
agent = Agent(reactor)
d = agent.request(
'GET', url,
Headers({'User-Agent': ['Twisted Web Client Example']}),
None)
d.addCallback(cbRequest)
d.addBoth(cbShutdown)
return d if __name__ == '__main__': for i in range(total_times):
curl("http://web.kuaipan.cn/static/images/pc.png") reactor.run() #root:~/test # time ./tc.py
#real 0m15.480s
#user 0m3.596s
#sys 0m0.720s

4,使用twisted网络库长连接,耗时也是很少,很快

#!/usr/bin/python

from sys import argv
from pprint import pformat #from twisted.internet.task import react
from twisted.internet import reactor
from twisted.web.http_headers import Headers from twisted.internet import reactor
from twisted.internet.defer import Deferred, DeferredList
from twisted.internet.protocol import Protocol
from twisted.web.client import Agent, HTTPConnectionPool total_times = 1000
times = 0 class IgnoreBody(Protocol):
def __init__(self, deferred):
self.deferred = deferred def dataReceived(self, bytes):
pass def connectionLost(self, reason):
self.deferred.callback(None) def cbRequest(response):
#print 'Response code:', response.code
finished = Deferred()
response.deliverBody(IgnoreBody(finished))
return finished pool = HTTPConnectionPool(reactor)
agent = Agent(reactor, pool=pool) def requestGet(url):
d = agent.request('GET', url)
d.addCallback(cbRequest)
return d def cbShutdown(ignored):
global times
times = times + 1
if total_times - 1 < times:
reactor.stop() def curl(url):
agent = Agent(reactor)
d = agent.request(
'GET', url,
Headers({'User-Agent': ['Twisted Web Client Example']}),
None)
d.addCallback(cbRequest)
d.addBoth(cbShutdown)
return d for i in range(total_times):
curl("http://web.kuaipan.cn/static/images/pc.png") reactor.run() #root:~/test # time ./tpc.py
#real 0m12.817s
#user 0m3.508s
#sys 0m0.528s

更多twisted参考:https://twistedmatrix.com/documents/current/web/howto/client.html#auto4

golang使用循环下载方式,和python使用循环下载方式耗时差不多,4分钟时间,瓶颈应该在网络

package main

import (
"fmt"
"net/http"
"io/ioutil"
) var totaltimes = func worker(url string) {
response, err := http.Get(url)
if err != nil {
return
}
defer response.Body.Close()
body, _ := ioutil.ReadAll(response.Body)
fmt.Println(len(body))
} func main() { for i := ; i < totaltimes;i ++ {
worker("http://web.kuaipan.cn/static/images/pc.png")
}
} //root:~/test # time ./got > goresult
//
//real 4m45.257s
//user 0m0.628s
//sys 0m0.632s

golang使用协程池方式模拟下载1000次,性能也要差很多(而且容易出现网络错误,最近出的go version go1.2rc4 linux/amd64要好一点 ,go1.1问题很多)

package main

import (
"fmt"
"net/http"
"io/ioutil"
"sync"
) var totaltimes =
var poolsize = func worker(linkChan chan string, wg *sync.WaitGroup) {
// Decreasing internal counter for wait-group as soon as goroutine finishes
defer wg.Done() for url := range linkChan {
// Analyze value and do the job here
response, err := http.Get(url)
if err != nil {
return
}
defer response.Body.Close()
body, _ := ioutil.ReadAll(response.Body)
fmt.Println(len(body))
//fmt.Println("Resp code", response.StatusCode)
}
} func main() {
var i int lCh := make(chan string)
wg := new(sync.WaitGroup)
// Adding routines to workgroup and running then
for i := ; i < poolsize; i++ {
wg.Add()
go worker(lCh, wg)
} for i = ; i < totaltimes;i ++ {
lCh <- "http://web.kuaipan.cn/static/images/pc.png"
}
close(lCh)
// Waiting for all goroutines to finish (otherwise they die as main routine dies)
wg.Wait()
} //root:~/test # time ./gotest > goresult
//
//real 0m25.250s
//user 0m0.772s
//sys 0m0.380s

twisted支持定时器,我们可以用来动态添加任务

from twisted.web.client import getPage
from twisted.internet import reactor class Getter(object): def __init__(self):
self._sequence = 0
self._results = []
self._errors = [] def add(self, url):
d = getPage(url)
d.addCallbacks(self._on_success, self._on_error)
d.addCallback(self._on_finish)
self._sequence += 1 def _on_finish(self, *narg):
self._sequence -= 1
print len(self._results), len(self._errors)
# if not self._sequence:
# reactor.stop() _on_success = lambda self, *res: self._results.append(res)
_on_error = lambda self, *err: self._errors.append(err) def run(self):
reactor.run()
return self._results, self._errors def jobtimer():
for url in ('http://www.google.com', 'http://www.yahoo.com', 'http://www.baidu.com'):
g.add(url)
reactor.callLater(1,jobtimer) reactor.callLater(2,jobtimer) #定时添加任务
g = Getter()
results, errors = g.run() #print len(results)
#print len(errors)

使用python网络库下载的更多相关文章

  1. 基于协程的Python网络库gevent

    import gevent def test1(): print 12 gevent.sleep(0) print 34 def test2(): print 56 gevent.sleep(0) p ...

  2. Python网络爬虫 - 下载图片

    下载博客园的logo from urllib.request import urlretrieve from urllib.request import urlopen from bs4 import ...

  3. python 第三方库下载

    C:\Python27\Scripts 路径下: easy_install.exe: C:\Python27\Scripts>easy_install.exe pycrypto pip.exe: ...

  4. python 第三方库下载地址

    http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml

  5. python基于协程的网络库gevent、eventlet

    python网络库也有了基于协程的实现,比较著名的是 gevent.eventlet 它两之间的关系可以参照 Comparing gevent to eventlet, 本文主要简单介绍一下event ...

  6. python常用库

    本文由 伯乐在线 - 艾凌风 翻译,Namco 校稿.未经许可,禁止转载!英文出处:vinta.欢迎加入翻译组. Awesome Python ,这又是一个 Awesome XXX 系列的资源整理,由 ...

  7. 156个Python网络爬虫资源

    本列表包含Python网页抓取和数据处理相关的库. 网络相关 通用 urllib - 网络库(标准库) requests - 网络库 grab - 网络库(基于pycurl) pycurl - 网络库 ...

  8. Python常用库大全

    环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具. pyenv – 简单的 Python 版本管理工具. Vex – 可以在虚拟环境中执行命令. v ...

  9. python的库小全

    环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具. pyenv – 简单的 Python 版本管理工具. Vex – 可以在虚拟环境中执行命令. v ...

随机推荐

  1. Linux常用指令(待补充)

    1.cd进入目录 2../shuntdown.sh  停止tomcat 3.ps -ef |grep +进程名  查看进程状态 4.kill +进程名   强杀kill -9 +进程 5./start ...

  2. windows8 安装IIS 和 添加网站(转)

    Internet Information Services(IIS,互联网信息服务),是由微软公司提供的基于运行Microsoft Windows的互联网基本服务.最初是Windows NT版本的可选 ...

  3. WPF中常用控件的属性

    Source = new BitmapImage( new Uri( WangCaiConfig.GetCurrentDirectory() + imgStr, UriKind.RelativeOrA ...

  4. C++中的string

    要想使用标准C++中string类,必须要包含 #include <string>// 注意是<string>,不是<string.h>,带.h的是C语言中的头文件 ...

  5. Android 一个抽奖应用的逆向破解全流程之加固自己应用

    转自: <a href="http://www.pedant.cn/2014/07/22/crack-a-draw-app/">http://www.pedant.cn ...

  6. poj 3469 Dual Core CPU 最小割

    题目链接 好裸的题....... 两个cpu分别作为源点和汇点, 每个cpu向元件连边, 权值为题目所给的两个值, 如果两个元件之间有关系, 就在这两个元件之间连边, 权值为消耗,这里的边应该是双向边 ...

  7. 【原创】JPEG图像密写研究(二) 哈夫曼树的建立

    [原创]记录自己研究的过程,仅供参考,欢迎讨论... 在根据JPEG图像文件结构读取完文件后,提取出其中DHT段,利用其中内容建立哈夫曼树,便于之后译码工作.这里需要注意的是文件中的哈夫曼表数量不固定 ...

  8. 无法打开 configsource 文件

    右键点击*.config文件,属性里的“复制到输出目录”选项,选择“始终复制”或“如果较新则复制”,这样生成或运行时,该文件就会出现在bin目录或obj目录中.

  9. Delphi2010新发现-类的构造和析构函数功能

    Delphi2010发布了. 虽然凭着对Delphi的热爱第一时间就安装了,但是现在可能是年纪大了,对新事物缺乏兴趣了.一直都没有仔细研究. 今天有点时间试了一下新功能. 本来C#和Delphi.NE ...

  10. 数学之路(3)-机器学习(3)-机器学习算法-SVM[7]

    SVM是新近出现的强大的数据挖掘工具,它在文本分类.手写文字识别.图像分类.生物序列分析等实际应用中表现出非常好的性能.SVM属于监督学习算法,样本以属性向量的形式提供,所以输入空间是Rn的子集. 图 ...