先来个同步版的:
#!/usr/bin/python
#coding:utf-8
import re
import urllib2
import sys
import os
hds={'User-Agent':'chrome/28.0.1500.72',}
#proxy_h=urllib2.ProxyHandler({'http':'http://127.0.0.1:8087'})
"""如果需要账号密码认证,则需要使用proxy_a=urllib2.HTTPBasicAuthHandler().add_password('realm','host','username','password'),并把proxy_a传入urllib2.bulid_opener的第二个参数"""
#opener=urllib2.build_opener(proxy_h)
#urllib2.install_opener(opener)
def getHtml(url):
page=urllib2.urlopen(urllib2.Request(url,None,hds)).read() #读取网页html源码
return page
def getImg(page):
r_img=re.compile(r"src=\"((http://|https://|)[\w/\.\-/]*\.(jpg|png|gif))\"",re.I)#编译生成一个正则规则,匹配相对绝对,和多种图片格式
for URL in r_img.findall(page):#做一个遍历
try:
if not URL[1]: #当它是相对路径时
URL=Url+'/'+URL[0] #把它变成绝对路径
else:
URL=URL[0] #直接是绝对路径
fileName=URL.split('/')[-1] #取文件名
print URL
img=urllib2.urlopen(urllib2.Request(URL,None,hds)).read()
open(fileName,'w').write(img).close()
except Exception,e:
pass
if __name__ == '__main__':
Url=sys.argv[1]
try:
os.mkdir('img')
except OSError,e:
if e.errno == 17:#如果是文件已经存在,则不做任何操作
pass
else: #如果是其他异常,则打印出异常,并退出程序
print e
sys.exit()
os.chdir('img')
getImg(getHtml(Url))
接下去是多线程版的:
#!/usr/bin/python
#coding:utf-8
import re
import urllib2,urllib,socket
import sys
import os
import time
import threading
hds={'User-Agent':'chrome/28.0.1500.72',}
#proxy_h=urllib2.ProxyHandler({'http':'http://127.0.0.1:8087'})
#opener=urllib2.build_opener(proxy_h)
#urllib2.install_opener(opener)
def getHtml(url):
page=urllib2.urlopen(urllib2.Request(url,None,hds)).read() #读取网页html源码
return page
class getImgThread(threading.Thread):
def __init__(self,imgUrl,fileName):
threading.Thread.__init__(self)
self.url=imgUrl
self.fileName=fileName
def run(self):
mutex.acquire()
print self.url
mutex.release()
urllib.urlretrieve(self.url,self.fileName)
if __name__ == '__main__':
socket.setdefaulttimeout(10)
Url=sys.argv[1]
try:
os.mkdir('img')
except OSError,e:
if e.errno == 17:#如果是文件已经存在,则不做任何操作
pass
else: #如果是其他异常,则打印出异常,并退出程序
print e
sys.exit()
os.chdir('img')
page=getHtml(Url)
r_img=re.compile(r"src=\"((http://|https://|)[\w/\.\-/]*\.(jpg|png|gif))\"",re.I)
mutex=threading.Lock()
threads=[]
for URL in r_img.findall(page):#做一个遍历
try:
if not URL[1]: #当它是相对路径时
URL=Url+'/'+URL[0] #把它变成绝对路径
else:
URL=URL[0] #直接是绝对路径
fileName=URL.split('/')[-1] #取文件名
threads.append(getImgThread(URL,fileName))
except Exception,e:
pass
for t in threads:
t.start()
for t in threads:
t.join()
print 'End'
再接下去是异步版的
#!/usr/bin/python
#coding:utf-8
import re
import urllib2
import sys
import os
from twisted.internet import defer,reactor
from twisted.web.client import getPage
hds={'User-Agent':'chrome/28.0.1500.72',}
def getHtml(url):
page=urllib2.urlopen(urllib2.Request(url,None,hds)).read() #读取网页html源码
return page
def getImg(page):
r_img=re.compile(r"src=\"((http://|https://|)[\w/\.\-/]*\.(jpg|png|gif))\"",re.I)#编译生成一个正则规则,匹配相对绝对,和多种图片格式
imgs=[]
errors=[]
urls=r_img.findall(page)
def saveImg(img,filename):
fd=open(filename,"wb")
fd.write(img)
fd.close()
imgs.append(filename)
def getError(_):
print _
errors.append(_)
def getFinished(_):
if len(errors)+len(imgs)==len(urls):
reactor.stop()
for URL in urls:#做一个遍历
if not URL[1]: #当它是相对路径时
URL=Url+'/'+URL[0] #把它变成绝对路径
else:
URL=URL[0] #直接是绝对路径
fileName=URL.split('/')[-1] #取文件名
print URL
deferred=getPage(URL)
deferred.addCallback(saveImg,fileName)
deferred.addErrback(getError)
deferred.addBoth(getFinished)
if __name__ == '__main__':
Url=sys.argv[1]
try:
os.mkdir('img')
except OSError,e:
if e.errno == 17:#如果是文件已经存在,则不做任何操作
pass
else: #如果是其他异常,则打印出异常,并退出程序
print e
sys.exit()
os.chdir('img')
d=getPage(Url)
d.addCallback(getImg)
reactor.run()
以上的异步使用了轮询,每次下载一副图片,都要去计算下,成功下载次数+失败下载次数是否等于整个任务数,这样就太累了,用不着,下面的是使用了deferlist的机制,当所有deferred都激活后,则执行结束任务。代码如下:
#!/usr/bin/python
#coding:utf-8
import re
import urllib2
import sys
import os
from twisted.internet import defer,reactor
from twisted.web.client import getPage
hds={'User-Agent':'chrome/28.0.1500.72',}
def getHtml(url):
page=urllib2.urlopen(urllib2.Request(url,None,hds)).read() #读取网页html源码
return page
def getImg(page):
r_img=re.compile(r"src=\"((http://|https://|)[\w/\.\-/]*\.(jpg|png|gif))\"",re.I)#编译生成一个正则规则,匹配相对绝对,和多种图片格式
urls=r_img.findall(page)
dlist=[] # deferred列表
def saveImg(img,filename):
fd=open(filename,"wb")
fd.write(img)
fd.close()
def getError(_):
print _
return None
def getFinished(_):
reactor.stop()
for URL in urls:#做一个遍历
if not URL[1]: #当它是相对路径时
URL=Url+'/'+URL[0] #把它变成绝对路径
else:
URL=URL[0] #直接是绝对路径
fileName=URL.split('/')[-1] #取文件名
print URL
deferred=getPage(URL,timeout=3)
dlist.append(deferred)
deferred.addCallback(saveImg,fileName)
deferred.addErrback(getError)
d=defer.DeferredList(dlist)
d.addBoth(getFinished) # 当列表中的deferred都激活后,才会激活这个
if __name__ == '__main__':
Url=sys.argv[1]
try:
os.mkdir('img')
except OSError,e:
if e.errno == 17:#如果是文件已经存在,则不做任何操作
pass
else: #如果是其他异常,则打印出异常,并退出程序
print e
sys.exit()
os.chdir('img')
d=getPage(Url)
d.addCallback(getImg)
reactor.run()