6188 网站图片爬虫

Spider

本次使用的为python3.4

爬取www.6188.com上壁纸

第一步,我们先看网站分析,寻找规律:

我们要抓取的是网站所有的图片,通过对网站结构的分析,发现其中规律:

  网站图片是按类区分的,每一个类别在主页(A)中有一个链接(B),该链接中有一个该类的列表(C),每一个类表中为图片listD),ist中有图片的真实地址

              ·大致结构图如下:

好了,网站结构了解了,循序渐进,一步步获取图片。

从主页开始分析其中包含的类别如图:

源码:

其中包含两大类,wallpaperphone,也就是说主页我们只需要找到包含两个关键字的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

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。