6188 网站图片爬虫
Spider
本次使用的为python3.4
爬取www.6188.com上壁纸
第一步,我们先看网站分析,寻找规律:
我们要抓取的是网站所有的图片,通过对网站结构的分析,发现其中规律:
网站图片是按类区分的,每一个类别在主页(A)中有一个链接(B),该链接中有一个该类的列表(C),每一个类表中为图片list(D),ist中有图片的真实地址
·大致结构图如下:
好了,网站结构了解了,循序渐进,一步步获取图片。
从主页开始分析其中包含的类别如图:
源码:
其中包含两大类,wallpaper和phone,也就是说主页我们只需要找到包含两个关键字的html连接,然后提取不同链接
首先定义一个读取网页的简单函数返回读取网页的内容:
import re import urllib.request as urllib def read_url(url_1): f=urllib.urlopen(url_1) re_url2=f.read() f.close() return re_url2
#读取主页,寻找匹配项:
#创建两个list,匹配项分别添加wallpaper和phonepaper wallpaper=[] phonepaper=[] index=‘http://www.6188.com‘ #由于read_url返回的为bytes类,re无法匹配,这里转换为str类型 index_1=str(read_url(index)) #匹配所有url,返回一个list index_url_list=re.findall(r‘(href=")([\S]{13,25}.html)‘,index_1) for url_1 in index_url_list: #判断是否为wallpaper if url_1[1].find(‘wallpaper‘)==1: wallpaper.append(‘http://www.6188.com‘+url_1[1]) #判断是否为phonepaper页 elif url_1[1].find(‘phone‘)==1: phonepaper.append(‘http://www.6188.com‘+url_1[1]) #去重 wallpaper=list(set(wallpaper)) phonepaper=list(set(phonepaper)) print(‘wallpaper:‘,wallpaper) print(‘phonepaper:‘,phonepaper)
运行结果如下:
wallpaper: [‘http://www.6188.com/wallpaper/1179_1.html‘, ‘http://www.6188.com/wallpaper/1160_1.html‘, ‘http://www.6188.com/wallpaper/1150_1.html‘, ‘http://www.6188.com/wallpaper/1233_1.html‘, ‘http://www.6188.com/wallpaper/1215_1.html‘, ‘http://www.6188.com/wallpaper/1193_1.html‘, ‘http://www.6188.com/wallpaper/1236_1.html‘, ‘http://www.6188.com/wallpaper/1200_1.html‘, ‘http://www.6188.com/wallpaper/1226_1.html‘, ‘http://www.6188.com/wallpaper/1208_1.html‘, ‘http://www.6188.com/wallpaper/1161_1.html‘, ‘http://www.6188.com/wallpaper/1205_1.html‘, ‘http://www.6188.com/wallpaper/1221_1.html‘, ‘http://www.6188.com/wallpaper/1210_1.html‘, ‘http://www.6188.com/wallpaper/1168_1.html‘, ‘http://www.6188.com/wallpaper/1182_1.html‘, ‘http://www.6188.com/wallpaper/1169_1.html‘, ‘http://www.6188.com/wallpaper/1188_1.html‘, ‘http://www.6188.com/wallpaper/1177_1.html‘, ‘http://www.6188.com/wallpaper/1165_1.html‘]
phonepaper: [‘http://www.6188.com/phone/1415_1.html‘, ‘http://www.6188.com/phone/1416_1.html‘, ‘http://www.6188.com/phone/1408_1.html‘, ‘http://www.6188.com/phone/1405_1.html‘, ‘http://www.6188.com/phone/1417_1.html‘, ‘http://www.6188.com/phone/1412_1.html‘, ‘http://www.6188.com/phone/1409_1.html‘, ‘http://www.6188.com/phone/1406_1.html‘, ‘http://www.6188.com/phone/1410_1.html‘, ‘http://www.6188.com/phone/1403_1.html‘, ‘http://www.6188.com/phone/1411_1.html‘, ‘http://www.6188.com/phone/1414_1.html‘, ‘http://www.6188.com/phone/1401_1.html‘, ‘http://www.6188.com/phone/1413_1.html‘, ‘http://www.6188.com/phone/1407_1.html‘]
至此已经完成了类别B的提取。
第二部,提取列表C:
以phonepaper中的http://www.6188.com/phone/1415_1.html为例,
我们所要提取的为图中两个链接,再看源码:
在实践中发现热门推荐中的壁纸源码格式与要提取的格式相同,会造成重复提取,因此添加去重操作,此过程中要创建以相应listC的图集名称文件夹,
代码:
phonepaper_l=[] def make_dir(main1): try: os.mkdir(‘c:\\123‘) print(‘新建文件夹‘,‘C:\123‘) except FileExistsError: print(‘文件夹‘,‘C:\123‘,‘已存在‘) main=read_url(main1).decode("utf-8") url=main_page_url=re.findall(r‘(<h3><a href=")([\S]{10,20}.html)(" target="_blank">)([\S]{10,30})(</a></h3>)‘,main) for tem in url: list_url=‘http://www.6188.com‘+tem[1] print(list_url) try: os.mkdir(‘c:\\123\\‘+tem[3]) print(‘新建文件夹‘,tem[3]) except FileExistsError: print(‘文件夹‘,tem[3],‘已存在‘) finally: find_next_page(list_url,tem[3]) print(‘this list end‘)
def phonepaper_url(phoneurl): #要提取其中的中文,指定编码格式 phonepage_in=read_url(phoneurl).decode("utf-8") print(‘phoneurl is::‘,phoneurl) ##在实际中存在没有页码的情况,此处判断,避免异常出现 if re.search(r‘([\d])(</a></div><a href=[\S]{10,20})(.html" class="next"></a></div>)‘,phonepage_in)==None: print(‘此页面没有页码,仅此一页‘) else: #匹配最后一页页码 phone_end=re.search(r‘([\d])(</a></div><a href=[\S]{10,20})(.html" class="next"></a></div>)‘,phonepage_in).group(1) #转为整形 phone_end_1=int(phone_end) phone_start_num1=1 #遍历一级list while phone_start_num1<phone_end_1: #每页的url phoneurl=phoneurl[:-6]+str(phone_start_num1)+‘.html‘ phone_start_num1=phone_start_num1+1 print(‘phoneurl‘,phoneurl) find_real_phonepage(phoneurl) ##在多页情况下最后一页无法匹配到 phone_end_num 做判断 else: #phone_start_num1=phone_end_1时 phoneurl=phoneurl[:-6]+str(phone_start_num1)+‘.html‘ read_endpage=read_url(phoneurl) url_one=re.findall(r‘(<div class="phone_img"><a href=")([\S]{10,30}.html)(" target="_blank"><img [\S]{20,100}" width="[\S]{2,5}[\s][\S]{5,15}[\s]alt=")([\S]{10,30})(")‘,phoneurl) #返回一个以元组为元素的list,遍历提取其中的图片lsitC for line in url_one: phone_url=‘http://www.6188.com‘+line[1] print(‘phone_url‘,phone_url) phone_name=line[3] #判断list C中的重复页面 添加到一个lsit中,判断list中是否包含此项,不包含添加,包含,重复 if phone_url in phonepaper_l: print(‘发现重复页面:‘,phone_url,‘name:‘,) else: phonepaper_l.append(phone_url) print(phone_name,phone_url) try: os.mkdir(‘c:\\123\\‘+line[3]) print(‘新建文件夹‘,line[3]) except FileExistsError: print(‘文件夹‘,line[3],‘已存在‘) finally: #进入相应文件夹,download image #find_down_image(phone_url,line[3]) print(‘page end‘) def find_real_phonepage(url): real_phonepage=read_url(url).decode("utf-8") #遍历图片list print(‘url::‘,url) #匹配最后行页码 phone_end_num=re.search (r‘([\d])(</a></div><a href=")([\S]{10,20}.html" class="next"></a></div> </div>)‘,str(real_phonepage)).group(1) phone_end_num2=int(phone_end_num) phone_start_num2=1 #遍历图片页码 while phone_start_num2<=phone_end_num2: url=url[:-6]+str(phone_start_num2)+‘.html‘ print(‘当前图片页:‘,url) #匹配image liist 地址 url_one=re.findall(r‘(<div class="phone_img"><a href=")([\S]{10,30}.html)(" target="_blank"><img [\S]{20,100}" width="[\S]{2,5}[\s][\S]{5,15}[\s]alt=")([\S]{10,30})(")‘,real_phonepage) phone_start_num2=phone_start_num2+1 for line in url_one: phone_url=‘http://www.6188.com‘+line[1] phone_name=line[3] #判断去重去除 热门图片的url if phone_url in phonepaper_l: print(‘发现重复页面‘,phone_url,‘name:‘,phone_name) else: phonepaper_l.append(phone_url) print(phone_name,phone_url) try: os.mkdir(‘c:\\13\\‘+line[3]) print(‘新建文件夹‘,line[3]) except FileExistsError: print(‘文件夹‘,line[3],‘已存在‘) finally: #进入相应文件夹,download image find_down_image(phone_url,line[3]) print(‘finally end‘) phonepaperurl(‘http://www.6188.com/phone/1415_1.html‘)
运行结果:
当前图片页: http://www.6188.com/phone/1415_1.html
小清新盆栽鲜花手机壁纸 http://www.6188.com/show/18661_1.html
新建文件夹 小清新盆栽鲜花手机壁纸
finally end
唯美鲜花安卓手机壁纸 http://www.6188.com/show/18359_1.html
新建文件夹 唯美鲜花安卓手机壁纸
finally end
鲜花娇艳唯美安卓手机壁纸 http://www.6188.com/show/18314_1.html
新建文件夹 鲜花娇艳唯美安卓手机壁纸
finally end
清新淡雅宽屏手机壁纸 http://www.6188.com/show/18184_1.html
新建文件夹 清新淡雅宽屏手机壁纸
finally end
静物写真唯美手机壁纸 http://www.6188.com/show/18101_1.html
新建文件夹 静物写真唯美手机壁纸
.....................................................
...................................................
发现重复页面 http://www.6188.com/show/18184_1.html name: 清新淡雅宽屏手机壁纸
发现重复页面 http://www.6188.com/show/18101_1.html name: 静物写真唯美手机壁纸
发现重复页面 http://www.6188.com/show/17916_1.html name: 微距下的美丽世界手机壁纸下载
发现重复页面 http://www.6188.com/show/17850_1.html name: 晶莹剔透的美味葡萄诱惑壁纸
发现重复页面 http://www.6188.com/show/17833_1.html name: 绿色美景安卓手机壁纸下载
发现重复页面 http://www.6188.com/show/17823_1.html name: 清新的鲜花手机壁纸下载
发现重复页面 http://www.6188.com/show/17792_1.html name: 虚焦唯美植物手机壁纸下载
发现重复页面 http://www.6188.com/show/17609_1.html name: 清新植物美景手机壁纸下载
发现重复页面 http://www.6188.com/show/18661_1.html name: 小清新盆栽鲜花手机壁纸
发现重复页面 http://www.6188.com/show/17833_1.html name: 绿色美景安卓手机壁纸下载
发现重复页面 http://www.6188.com/show/18184_1.html name: 清新淡雅宽屏手机壁纸
发现重复页面 http://www.6188.com/show/17150_1.html name: 小清新意花卉超大手机壁纸
完成第二步。
第三步:遍历listD 提取真是的图片地址
看图
如上图所示,遍历list D提取图片真实地址
代码如下:
def find_down_image(url,path_list): url_line=read_url(url) #忽略类似/show/18269_1.html不存在的异常 if url_line==‘error‘: pass else: se=re.search(r‘([_])([\d]{1,2})(.html" class="pg_next">[\S]{4,30}</a></div>)‘,str(url_line)).group(2) se_endnum=int(se) se_startnum=0 while se_startnum<se_endnum: se_startnum=se_startnum+1 url1=url[:-6]+str(se_startnum)+‘.html‘ print(‘url::‘,url1) url_line1=read_url(url1) if url_line1==‘error‘: break else: #正常情况下处理寻找最终url se1=re.search(r‘(/show.php[\S]{10,100})(" title="" target="_blank">)‘,str(url_line1)).group(1) image_url=‘http://www.6188.com‘+se1 print(‘image_url:‘,image_url) #调用down函数 down_image(image_url,path_list)
找到真实图片地址:
然后读取文件到本地,定义一个download函数
#函数传入两个参数,图片所在页面地址,一个包含名称的路径 def down_image(image_url,path_list): final_page=str(read_url(image_url)) #真实地址 final_url=re.search(r‘(<img src=\‘)([\S]{20,100})(\‘ />)‘,final_page).group(2) #提取后十位充当文件名 name=image_url[-10:] dir_name=‘C:\\123\\‘+path_list+‘\\‘+name print(name) dir_image=image_url[-10:] #判断文件是否存在 if os.path.exists(dir_name): print(‘文件‘,name,‘已存在‘) else: #下载图片,并保存本地 image_b=read_url(final_url) with open (dir_name,‘wb+‘) as i: i.write(image_b) i.close() #Image.Image.save(im,image_url[-10:16]) print(‘完成下载 ‘,image_url[-10:16])
由于网站中存在错误页面:
因此在read_url()中做异常处理,返回一个‘error’,下面在读取时候做判断,上文代码中以做说明。
def read_url(url_1): ##由于网站中存在pageerror页面例如:/show/17114_4.html以后的页面 ##在调用read_url函数时,判断返回值是否为error, try: f=urllib.urlopen(url_1) re_url2=f.read() #print(re_url2) f.close() #解决网站中出现pageerror问题 return re_url2 except Exception: print(‘catch error‘) return ‘error‘
最后,遍历phonepaper,依次调用 phonepaper_url()函数即可实现
for url in phonepaper: print(‘phonepaper‘) phonepaper_url(url)
同样的,可以下载wallpaper中的图片。
上张图:
本文出自 “renzhes” 博客,请务必保留此出处http://renzhes.blog.51cto.com/7070206/1579880
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。