前篇回顾:下载一个类型集合的全部图片 本篇目标:获得一个集合页面中所有集合中所有的图片
使用urllib2获取已知集合网页页面的HTML代码,首先使用正则表达式获取本页图片集合的url,根据上篇所写戏在图片集合的函数 def getImgAssemble(url, fileName, filePath):
将集合中所有图片下载到指定文件夹,并将文件夹命名为图片集合标题名,然后判断是否还有下一页。如果有的话则进入下一页进行同样的动作,直到最后一页则集合页面所有图片下载完毕。
本篇将使用threading多线程和线程锁使下载并发执行,以增加效率和运行速度。
有关python多线程:
请自行AOL或百度去。。。。
集合页面url = 'http://desk.zol.com.cn/meinv/'
首先建个函数def getImgCatalog(url, filePath):,然后往里面塞我们需要的东西就好咯。先写好基础到,获取已知url的HTML。
代码如下:
- 73 def getImgCatalog(url, filePath):
- 74 if not os.path.exists(filePath):
- 75 os.makedirs(filePath)
- 76 if not filePath.endswith('/'):
- 77 filePath += '/'
- 78
- 79 user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
- 80 headers = {'User-Agent' : user_agent}
- 81
- 82 request = urllib2.Request(url, headers=headers)
- 83 content = urllib2.urlopen(request).read().decode('GBK')
- 84
- 85 f = open('url.txt', 'w')
- 86 f.write(content.encode('utf-8'))
- 87 f.close()
- 88
- 89 print content
- 90
部分结果如下:
接下来我们可以使用正则表达式从HTML中提取我们需要的信息啦。
根据上篇我们所写下载集合图集的函数def getImgAssemble(url, fileName, filePath):和我们的需求,我们需要获取这些信息:
图片集合的url:使用来作为函数getImgAssemble的url
图片集合title:作为函数getImgAssemble的fileName。
OK,爬出本页全部图片暂时需要这些信息。
获取图片集合的url,HTML代码如下:
获取其中url和title的正则表达式为:
'<li\s+class="photo-list-padding"><a\s+class="pic"\s+href="(.+?)"\s+target=".+?"\s+hidefocus=".+?"><img\s*width=".+?"\s+height=".+?"\s+alt="(.+?)".+?/>'
增加了正则表达式的代码如下:
- 73 def getImgCatalog(url, filePath):
- 74 if not os.path.exists(filePath):
- 75 os.makedirs(filePath)
- 76 if not filePath.endswith('/'):
- 77 filePath += '/'
- 78
- 79 user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
- 80 headers = {'User-Agent' : user_agent}
- 81
- 82 request = urllib2.Request(url, headers=headers)
- 83 content = urllib2.urlopen(request).read().decode('GBK')
- 84
- 85 pattern = re.compile('<li\s+class="photo-list-padding"><a\s+class="pic"\s+href="(.+?)"\s+target=".+?"\s+hid efocus=".+?"><img\s*width=".+?"\s+height=".+?"\s+alt="(.+?)".+?/>', \
- 86 re.S)
- 87 imgInfoList = re.findall(pattern, content)
- 88
- 89 for item in imgInfoList:
- 90 sUrl = mUrl + item[0]
- 91
- 92 print sUrl
- 93 print item[1]
- 94
结果如下图:
我们已经得到了我们想要的结果。
然后再将函数getImgAssemble加进去。
我们再加一个显示运行时间的函数在main()里面以计算程序运行上时间:
import datetime
startTime = datetime.datetime.now()
。
。
endTime = datetime.datetime.now()
print (endTime-startTime).seconds
print "count : %d" %count
增加代码如下:
- 74 def getImgCatalog(url, filePath):
- 75 if not os.path.exists(filePath):
- 76 os.makedirs(filePath)
- 77 if not filePath.endswith('/'):
- 78 filePath += '/'
- 79
- 80 user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
- 81 headers = {'User-Agent' : user_agent}
- 82
- 83 request = urllib2.Request(url, headers=headers)
- 84 content = urllib2.urlopen(request).read().decode('GBK')
- 85
- 86 pattern = re.compile('<li\s+class="photo-list-padding"><a\s+class="pic"\s+href="(.+?)"\s+target=".+?"\s+hid efocus=".+?"><img\s*width=".+?"\s+height=".+?"\s+alt="(.+?)".+?/>', \
- 87 re.S)
- 88 imgInfoList = re.findall(pattern, content)
- 89
- 90 for item in imgInfoList:
- 91 sUrl = mUrl + item[0]
- 92 getImgAssemble(sUrl, item[1], filePath)
- 93
main:
- 95 def main():
- 96 startTime = datetime.datetime.now()
- 97
- 98 #img save path
- 99 savePath = os.getcwd()
- 100
- 101 url = 'http://b./desk/bizhi/image/7/960x600/1450950428732.jpg'
- 102 #img name4
- 103 imgName = 'pic1.jpg'
- 104 #downloadImg(url, imgName, savePath)
- 105
- 106 sUrl = 'http://desk.zol.com.cn/bizhi/6128_75825_2.html'
- 107 fileName = 'meinv'
- 108 #getImgAssemble(sUrl, fileName, savePath)
- 109
- 110 cUrl = 'http://desk.zol.com.cn/meinv/'
- 111 getImgCatalog(cUrl, savePath)
- 112
- 113 endTime = datetime.datetime.now()
- 114 print '\ntotal running time : %d s' %(endTime-startTime).seconds
- 115
结果截图:
时间用了68s,没有比较就不知道这个时间是长还是短。
下面来加个多线程和线程锁,代码如下:
- 75 catalogLock = threading.Lock()
- 76 def getImgCatalog(url, filePath):
- 77 if not os.path.exists(filePath):
- 78 os.makedirs(filePath)
- 79 if not filePath.endswith('/'):
- 80 filePath += '/'
- 81
- 82 user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
- 83 headers = {'User-Agent' : user_agent}
- 84
- 85 request = urllib2.Request(url, headers=headers)
- 86 content = urllib2.urlopen(request).read().decode('GBK')
- 87
- 88 pattern = re.compile('<li\s+class="photo-list-padding"><a\s+class="pic"\s+href="(.+?)"\s+target=".+?"\s+hidefocus= ".+?"><img\s*width=".+?"\s+height=".+?"\s+alt="(.+?)".+?/>', \
- 89 re.S)
- 90 imgInfoList = re.findall(pattern, content)
- 91
- 92 threads = []
- 93 for item in imgInfoList:
- 94 sUrl = mUrl + item[0]
- 95
- 96 #add thread
- 97 if catalogLock.acquire():
- 98 t = threading.Thread(target=getImgAssemble, args=(sUrl, item[1], filePath))
- 99 t.setDaemon(True)
- 100 threads.append(t)
- 101 catalogLock.release()
- 102
- 103 for i in range(len(threads)):
- 104 threads[i].start()
- 105 for i in range(len(threads)):
- 106 threads[i].join(30)
- 107
结果如下截图:
用时15s。可以看出,时间明显减少。
其实中间出了个问题困扰了很久。
有时候跑到中间会假死,然后ctrl+c并不能关闭线程,后来发现join里面加一个timeout就可以了,数值可以随意,但是要设的大一点,因为线程里面下载图片不是按顺序逐个下载的,一个图片可能挂起很长时间才会被下载,而且设置的大小并不影响结果时间,我们只是想把能下载下来的图片全部下载下来就好。
希望有谁能提供解决办法解决假死问题。
接下来判读是否有下一页,有的话获取下一页的url。
有下一个的HTML如下:
最后一页的HTML如下截图:
其实我们只需要判断是否有’id="pageNext"‘就可以判断是否有下一页了。
如果有’id="pageNext"‘,则利用正则表达式‘<a\s+id="pageNext"\s+href="(.+?)"\s*class="next"\s+target=".+?">’获取到下页的url。
整体代码如下:
- #/usr/bin/env python
-
- import os
- import re
- import urllib
- import urllib2
- import datetime
- import threading
-
- mUrl = 'http://desk.zol.com.cn'
-
- def downloadImg(url, imgName, savePath):
- if savePath == '':
- return 'image save path is nil.'
- if imgName == '':
- return 'image is nil.'
- if url == '':
- return 'url is nil.'
-
- if not os.path.exists(savePath):
- os.makedirs(savePath)
- if not savePath.endswith('/'):
- savePath += '/'
-
- savePathName = savePath + imgName
- urllib.urlretrieve(url, savePathName)
-
- print url
-
- def getImgAssemble(url, fileName, filePath):
- if not os.path.exists(filePath):
- os.makedirs(filePath)
- if not filePath.endswith('/'):
- filePath += '/'
- if not fileName in filePath:
- filePath += fileName
-
- print '******', url
- user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
- headers = {'User-Agent' : user_agent}
-
- tmpUrl = url
- while True:
- try:
- request = urllib2.Request(tmpUrl, headers=headers)
- content = urllib2.urlopen(request).read().decode('GBK')
- imgUrl = re.search('<img\s+id="bigImg"\s+src="(.+?)"\s*srcs=".+?"\s+width="\d+"\s+height="\d+">', \
- content).group(1)
- imgCount = re.search('<h3><a\s+id="titleName"\s+href=".+?">.+?</a><span>.+?(\d+).+?</span></h3>', \
- content).group(1)
-
- imgSuffix = re.search('http://.+?\..+?/.+?\.(.+?)$', \
- imgUrl).group(1)
- imgName = fileName + imgCount + '.' + imgSuffix
- downloadImg(imgUrl, imgName, filePath)
-
- nextUrlFlag = re.search('<a\s+id="pageNext"\s+class="next"\s+href="(.+?)"\s+title=".+?">', \
- content).group(1)
-
- if not "javascript:" in nextUrlFlag:
- tmpUrl = mUrl + nextUrlFlag
- continue
- else:
- print '\n'
- break
-
- except AttributeError:
- print 'attributeError'
- except urllib2.URLError, e:
- if hasattr(e, 'code'):
- print e.code
- if hasattr(e, 'reason'):
- print e.reason
-
- catalogLock = threading.Lock()
- def getImgCatalog(url, filePath):
- if not os.path.exists(filePath):
- os.makedirs(filePath)
- if not filePath.endswith('/'):
- filePath += '/'
-
- user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
- headers = {'User-Agent' : user_agent}
- tmpUrl = url
- while True:
- request = urllib2.Request(tmpUrl, headers=headers)
- content = urllib2.urlopen(request).read().decode('GBK')
-
- pattern = re.compile('<li\s+class="photo-list-padding"><a\s+class="pic"\s+href="(.+?)"\s+target=".+?"\s+hidefocus=".+?"><img\s*width=".+?"\s+height=".+?"\s+alt="(.+?)".+?/>', \
- re.S)
- imgInfoList = re.findall(pattern, content)
-
- threads = []
- for item in imgInfoList:
- sUrl = mUrl + item[0]
-
- #add thread
- if catalogLock.acquire():
- t = threading.Thread(target=getImgAssemble, args=(sUrl, item[1], filePath))
- t.setDaemon(True)
- threads.append(t)
- catalogLock.release()
-
- for i in range(len(threads)):
- threads[i].start()
- for i in range(len(threads)):
- threads[i].join(30)
-
- if not 'id="pageNext"' in content:
- break
- else:
- tmpUrl = mUrl + re.search('<a\s+id="pageNext"\s+href="(.+?)"\s*class="next"\s+target=".+?">', \
- content).group(1)
-
- def main():
- startTime = datetime.datetime.now()
-
- #img save path
- savePath = os.getcwd()
-
- url = 'http://b./desk/bizhi/image/7/960x600/1450950428732.jpg'
- #img name4
- imgName = 'pic1.jpg'
- #downloadImg(url, imgName, savePath)
-
- sUrl = 'http://desk.zol.com.cn/bizhi/6128_75825_2.html'
- fileName = 'meinv'
- #getImgAssemble(sUrl, fileName, savePath)
-
- cUrl = 'http://desk.zol.com.cn/meinv/'
- cFilePath = savePath+'/meinv'
- getImgCatalog(cUrl, cFilePath)
-
- endTime = datetime.datetime.now()
- print '\ntotal running time : %d s' %(endTime-startTime).seconds
-
-
- if __name__ == '__main__':
- main()
运行结果如下 :
文件总共1.64GB,用时494s,大概3.4Mb/s,网速的话平时迅雷下载会员高速离线下载差不多5Mb/s。
速度来说,还可以吧。
the end
谢谢
下篇预告:获取整个网站所有类型的壁纸
|