Python网络爬虫小试刀——抓取ZOL桌面壁纸图片3

news/2024/11/23 9:27:34/

前篇回顾:下载一个类型集合的全部图片
本篇目标:获得一个集合页面中所有集合中所有的图片

使用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 += '/'7879     user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'80     headers = {'User-Agent' : user_agent}8182     request = urllib2.Request(url, headers=headers)83     content = urllib2.urlopen(request).read().decode('GBK')8485     f = open('url.txt', 'w')86     f.write(content.encode('utf-8'))87     f.close()8889     print content90
部分结果如下:


接下来我们可以使用正则表达式从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 += '/'7879     user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'80     headers = {'User-Agent' : user_agent}8182     request = urllib2.Request(url, headers=headers)83     content = urllib2.urlopen(request).read().decode('GBK')8485     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)8889     for item in imgInfoList:90         sUrl = mUrl + item[0]9192         print sUrl93         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 += '/'7980     user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'81     headers = {'User-Agent' : user_agent}8283     request = urllib2.Request(url, headers=headers)84     content = urllib2.urlopen(request).read().decode('GBK')8586     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)8990     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()9798     #img save path99     savePath = os.getcwd()
100
101     url = 'http://b.zol-img.com.cn/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,没有比较就不知道这个时间是长还是短。

下面来加个多线程和线程锁,代码如下:

    import threading
 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 += '/'8182     user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'83     headers = {'User-Agent' : user_agent}8485     request = urllib2.Request(url, headers=headers)86     content = urllib2.urlopen(request).read().decode('GBK')8788     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)9192     threads = []93     for item in imgInfoList:94         sUrl = mUrl + item[0]9596         #add thread97         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 pythonimport os
import re
import urllib
import urllib2
import datetime
import threadingmUrl = '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 + imgNameurllib.urlretrieve(url, savePathName)print urldef getImgAssemble(url, fileName, filePath):if not os.path.exists(filePath):os.makedirs(filePath)if not filePath.endswith('/'):filePath += '/'if not fileName in filePath:filePath += fileNameprint '******', urluser_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'headers = {'User-Agent' : user_agent}tmpUrl = urlwhile 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 + '.' + imgSuffixdownloadImg(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 + nextUrlFlagcontinueelse:print '\n'breakexcept AttributeError:print 'attributeError'except urllib2.URLError, e:if hasattr(e, 'code'):print e.codeif hasattr(e, 'reason'):print e.reasoncatalogLock = 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 = urlwhile 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 threadif 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:breakelse: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 pathsavePath = os.getcwd()url = 'http://b.zol-img.com.cn/desk/bizhi/image/7/960x600/1450950428732.jpg'#img name4imgName = '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).secondsif __name__ == '__main__':main()
运行结果如下




文件总共1.64GB,用时494s,大概3.4Mb/s,网速的话平时迅雷下载会员高速离线下载差不多5Mb/s。
速度来说,还可以吧。

the end
谢谢

下篇预告:获取整个网站所有类型的壁纸


http://www.ppmy.cn/news/205953.html

相关文章

Python运用urllib2和BeautifulSoup爬取网站ZOL桌面壁纸上的精美电脑壁纸

Python运用urllib2和BeautifulSoup爬取网站ZOL桌面壁纸上的精美电脑壁纸 #!/usr/bin/env python # -*- coding: utf-8 -*- # Time : 2017/7/28 13:00 # File : SpyImg.py""" 爬取壁纸 """from bs4 import BeautifulSoup import urllib2 i…

Python网络爬虫小试刀——抓取ZOL桌面壁纸图片4

前篇回顾&#xff1a;获得一个类型集合页面中所有集合中的图片 本篇目标&#xff1a;获取整个网站所有类型集合的壁纸图片 使用urllib2&#xff0c;正则表达式&#xff0c;threading等高效下载网站’http://desk.zol.com.cn‘中壁纸图片。 使用urllib2获取url &#xff1d; …

PHP7新特性详细介绍(一)

一、标量类型与返回值类型声明 标量类型声明 标量类型声明有两种模式&#xff1a; 1、强制模式 2、严格模式 declare(strict_types1); 代码中通过指定 strict_types的值&#xff08;1或者0&#xff09;&#xff0c;1表示严格类型校验模式&#xff0c;作用于函数调用和返回语…

【深入浅出Spring Security(五)】自定义过滤器进行前后端登录认证

自定义过滤器 一、自定义过滤器自定义登录认证过滤器自定义 LoginFilter配置 LoginFilter测试 二、总结 一、自定义过滤器 在【深入浅出Spring Security&#xff08;二&#xff09;】Spring Security的实现原理 中小编阐述了默认加载的过滤器&#xff0c;里面有些过滤器有时并…

Golang vs Rust ——服务端编程应该选择哪种语言

为服务端编程选择一种语言应该基于你的长期目标和项目的要求&#xff0c;因此&#xff0c;盲目地问我应该雇用 Go 开发人员还是应该选择 Rust 进行开发并不能帮助你解决问题。 然而&#xff0c;如果你发现自己陷入了困境&#xff0c;那么这篇文章将为你解惑。下面让我们开始吧…

nornir

1、安装依赖 pip install -r requirements.txt 2、安装python虚拟环境 a、安装虚拟环境 pip3 install virtualenv b、安装虚拟环境管理工具 pip3 install virtualenvwrapper c、在家目录下创建隐藏目录 .virtualenvs&#xff0c;所有虚拟环境都放在此目录下 cd ~ mkdir .virtu…

ARNOR

ARNOR 链接: 数据集 提取码: 6cgu 1.一 论文导读2.二 论文精读3.三 代码实现4.四 问题思索 《ARNOR&#xff1a;Attention Regularization based Noise Reduction for Distant Supervision Relation Classification》 —基于注意力正则化的ARNOR框架 作者&#xff1a;Wei jia…

errnor

linux errno查看和使用_believe209的博客-CSDN博客_linux 获取errno Linux网络编程常见错误码及分析_Justice_Gao的博客-CSDN博客 Linux socket里的send和recv&#xff0c;阻塞与非阻塞socket、TCP与UDP的区别_瓶子里de肥皂泡的博客-CSDN博客 同步、异步、阻塞、非阻塞&…