美文网首页python爬虫计算机杂谈
Scrapy爬女神图(一)—— 这是你们要的小姐姐

Scrapy爬女神图(一)—— 这是你们要的小姐姐

作者: Wakingup88688 | 来源:发表于2017-04-13 19:42 被阅读1644次
    Scrapy第二篇: 多层次网页爬取 | 图片爬取

    (先随便放个封面图)


    看到这个标题,目测一大波老司机心里开始os:难道又是 妹子图???
    (我。。。我还能说什么)
    89768193

    宝宝的品位可不一般的好吧!!!
    这年代最流行什么呀?
    当然是“女神”,“校花”啦!!!(额,说“网红”的当我没说。。)
    颜值高,有范儿,关键气质逆天对不对~

    比如这样:


    这样:


    或者这样:


    这样:


    </br>
    不错吧?(嘿嘿据说最后这个还是我川的妹子~)心动不如行动,今天我们就用Scrapy把诸位女神收入囊中
    目标网站:唯一图库
    搜索关键词:校花
    唯一图库

    一、步骤

    1、首先分析网站
    打开上面这个页面


    下拉就是各位MM的简介 下拉到最底部就是这样 第2页

    点完之后发现,真的只有6页。


    查看源代码

    随便点击进入某个主页


    查看源码

    看完第一个图,来看后面的图


    第二个图是这样
    第三个图是这样

    可以看出规律了吧,皆是是 url=xxx+_n.html(n为1,2,3...)的结构,只要获得前面那一串和最大页数就可以构造了。

    但是进一步分析就会发现,每个MM个人页面内图片的URL结构是不一样的(这里也要注意),如下所示:



    基本上无规律可循,不能构造出来,只能从源码中获取图片真实链接

    2、思路
    用Scrapy爬取思路:
    1)先获取首页siteURL,以及标题
    2)然后由其进入MM个人页面获取最大页数Num第一个图片URL
    3)构造每一个图片地址pageURL
    4)requests获取源码中具体原图地址detailURL
    5)获取图片并保存入文件,以1)中标题作为文件名

    这里就涉及到了多层次页面爬取的问题
    怎么办呢,不要忘了,可以用meta传参数。

    二、代码

    首先来看整个项目的文件结构
    以为没有本项目用到middlewares中间件,所以删去了


    entrypoint是一个设置,使得程序可以在IDE中运行
    只需要调用entrypoint即可运行程序
    from scrapy.cmdline import execute
    execute(['scrapy', 'crawl', 'XiaoHua'])
    

    来看具体分块代码实现:

    1、items部分
    # -*- coding: utf-8 -*-
    
    # Define here the models for your scraped items
    # See documentation in:
    # http://doc.scrapy.org/en/latest/topics/items.html
    import scrapy
    
    class XiaohuaItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field() 
        siteURL=scrapy.Field() #首页中各MM的URL
        pageURL=scrapy.Field() #每一张图片入口URL
        detailURL=scrapy.Field() #图片原图地址
        title=scrapy.Field()  #MM标题
        fileName=scrapy.Field() #文件夹名,每一个MM一个文件夹
        path=scrapy.Field()  #图片存储路径(绝对路径)
    

    </br>

    2、settings部分
    # -*- coding: utf-8 -*-
    # Scrapy settings for XiaoHua project
    
    BOT_NAME = 'XiaoHua'
    SPIDER_MODULES = ['XiaoHua.spiders']
    NEWSPIDER_MODULE = 'XiaoHua.spiders'
    
    #是否遵循机器人规则
    ROBOTSTXT_OBEY = False
    #默认是16,一次可以请求的最大次数
    CONCURRENT_REQUESTS=32
    #下载延迟
    DOWNLOAD_DELAY=0.1
    #Cookies设置
    COOKIES_ENABLED = False
    #headers设置
    DEFAULT_REQUEST_HEADERS = {
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding':'gzip, deflate, sdch',
    'Accept-Language':'zh-CN,zh;q=0.8',
    'Cache-Control':'max-age=0',
    'Connection':'keep-alive',
    'User-Agent':'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
    
    #管道设置
    ITEM_PIPELINES = {'XiaoHua.pipelines.XiaohuaPipeline': 300}
    

    </br>

    3、spiders部分
    # --coding:utf-8--
    import scrapy
    from XiaoHua.items import XiaohuaItem
    from scrapy.http import Request
    import requests
    import re
    import os
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    class Myspider(scrapy.Spider):
        name='XiaoHua'
        allowed_domains=['mmonly.cc']
        base=r'F:/Desktop/code/info/XiaoHua/'
        def start_requests(self):
            #一共有6页
            for i in range(1,7):
                url='https://www.mmonly.cc/tag/xh1/'+str(i)+'.html'
                yield Request(url,callback=self.parse_one)
    
        def parse_one(self,response):
            #创建一个大的list存储所有的item
            items=[]
            pattern=re.compile(r'<div class="title".*?<a.*?href="(.*?)">(.*?)</a></span></div>',re.S)
            mains=re.findall(pattern,response.text)
            for main in mains:
                #创建实例,并转化为字典
                item=XiaohuaItem()
                item['siteURL']=main[0]
                item['title']=main[1]
                item['fileName']=self.base+item['title']
                items.append(item)
    
            for item in items:
                #创建文件夹
                fileName=item['fileName']
                if not os.path.exists(fileName):
                    os.makedirs(fileName)
                #用meta传入下一层
                yield Request(url=item['siteURL'],meta={'item1':item},callback=self.parse_two)
    
        def parse_two(self,response):
            #传入上面的item1
            item2=response.meta['item1']
            source=requests.get(response.url)
            html=source.text.encode('utf-8')
            #用正则提取页数
            pattern=re.compile(r'共(.*?)页',re.S)
            Num=re.search(pattern,html).group(1)
            items=[]
            for i in range(1,int(Num)+1):
                #注意这里,创建实例的位置
                item=XiaohuaItem()
                item['fileName']=item2['fileName']
                #构造每一个图片的存储路径
                item['path']=item['fileName']+'/'+str(i)+'.jpg'
                #构造每一个图片入口链接,以获取源码中的原图链接
                item['pageURL']=response.url[:-5]+'_'+str(i)+'.html'
                items.append(item)
            for item in items:
                yield Request(url=item['pageURL'],meta={'item2':item},callback=self.parse_three)
    
        def parse_three(self,response):
            item=XiaohuaItem()
            #传入上面的item2
            item3=response.meta['item2']
            #匹配正则获取图片真实地址detailURL
            pattern=re.compile(r'<li class="pic-down h-pic-down"><a target="_blank" class="down-btn" href=\'(.*?)\'>.*?</a>',re.S)
            URL=re.search(pattern,response.text).group(1)
            item['detailURL']=URL
            item['path']=item3['path']
            item['fileName']=item3['fileName']
            yield item
    

    </br>

    4、pipelines部分
    # -*- coding: utf-8 -*-
    import requests
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    #用requests的get方法获取图片并保存入文件
    class XiaohuaPipeline(object):
        def process_item(self, item, spider):
            detailURL=item['detailURL']
            path=item['path']
            fileName=item['fileName']
    
            image=requests.get(detailURL)
            f=open(path,'wb')
            f.write(image.content)
            f.close()
            print u'正在保存图片:',detailURL
            print u'图片路径:',path
            print u'文件:',fileName
            return item
    

    写完代码,直接调用entrypoint即可在IDE中运行(我用的Pycharm)
    这个小项目我也放到github上了:https://github.com/LUCY78765580/Python-web-scraping/tree/master/XiaoHua (如果您觉得有帮助,可以star我哟~)

    三、结果

    最后结果就是这样的:



    一共抓取图片2114张
    文件是这样 随便打开是这样

    </br>

    四、参考:

    meta传参这一块,参考了博客:
    http://www.jianshu.com/p/c77c59aa4b92

    五、我分享我快乐

    这里是你们要的小姐姐_

    百度网盘https://pan.baidu.com/s/1bpxPRen
    密码:25gq

    下载下来稍稍解压即可,不用太感谢(顺手点个赞就行),我是造福人类的小天使~
    </br>

    六、总结

    最后,总结本篇关键:
    1、Scrapy爬取多级网页结构(主要用meta传递数据)
    2、Scrapy爬取图片的一般方法(别的方法放下次讨论)
    对了,不知各位有没有发现,我们在爬唯一图库时,竟然如此顺利,没有遇到任何反爬。感叹:良心网站呀

    970168903

    本篇就是这样啦~

    相关文章

      网友评论

      • qqnv:好像现在爬的全是目录,没有小姐姐:joy:
      • 六月之城:艳萤老司机!!!
      • 赵镇:为啥没用BeautifulSoup反而用正则?
      • 1_a3ab:python3还是2啊
        Wakingup88688: @1_a3ab 2.7哦
      • 造数科技:啊哈哈,没想到这么快就写好了
        Wakingup88688: @崔斯特呀 汤不热是什么鬼
        造数科技: @Wakingup88688 我要爬汤不热😂
        Wakingup88688:宅男福利:smirk:
      • 张照博:😑😑😑多谢赐教。。最近课程实验太多了。。学不过来了
        Wakingup88688: @HustWolf 天啊(#゚Д゚)
        张照博:对头。。。正在处理实验报告🙄🙄🙄(一份机械设计,两份数控技术)
        Wakingup88688: @HustWolf 哇哦,机械学院的
      • 张照博:6666我要的小姐姐。你全都有
        Wakingup88688: @HustWolf 将tag换成其它,也可以下载别的主题(点到为止,自己去分析了哈)🙃🙃

      本文标题:Scrapy爬女神图(一)—— 这是你们要的小姐姐

      本文链接:https://www.haomeiwen.com/subject/tigpattx.html