Scrapy爬取图片并重命名总结

文章目录

    • Scrapy爬取图片并重命名总结
      • 项目分析:
      • 开始项目:
      • 启动项目:
    • 总结

Scrapy爬取图片并重命名总结

项目分析:

1、现在很多网页都是动态加载资源,数据都不在静态html模板上,都是通过重定向从json文件中加载而来,因此只要抓取json数据包即可,这是一种捷径,比较容易,并不利于爬虫的学习,所以以后还是在数据实在不好得到的情况下使用

2、开发环境及工具介绍

python 3.6

scrapy 1.7.3

XPath选择器

工具:pycharm


开始项目:

https://www.douyu.com/api/v1/getVerticalRoom?limit=20&offset=0 数据地址

1、合适的位置创建project

进入cmd命令窗口:

  • scrapy startproject Douyu 创建爬虫项目
  • scrapy genspider douyu “douyu.com” 创建爬虫文件
  • 创建一个保存图片的文件夹,记住路径,需要写在配置文件里
  • 项目结构
#  pycache是py的缓存文件不用理会

│  scrapy.cfg                     
│
├─Douyu                          
│  │  items.py                     
│  │  middlewares.py
│  │  pipelines.py
│  │  settings.py
│  │  init.py
│  │
│  ├─spiders
│  │  │  douyu.py
│  │  │  init.py
│  │  │
│  │  └─pycache
│  │          douyu.cpython-36.pyc
│  │          init.cpython-36.pyc
│  │
│  └─pycache
│          items.cpython-36.pyc
│          pipelines.cpython-36.pyc
│          settings.cpython-36.pyc
│          init.cpython-36.pyc
│
└─images

2、分析json数据

Scrapy爬取图片并重命名总结_第1张图片

需要爬取的字段 nickname vertical_src ,并且重命名图片名称,使用nickname命名

  • 定义item.py

    import scrapy
    
    class DouyuItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        # 主播昵称
        nickname = scrapy.Field()
        # 图片链接
        imagelink = scrapy.Field()
    
  • 编写爬虫文件 douyu.py

    # -*- coding: utf-8 -*-
    import scrapy
    import json
    
    from Douyu.items import DouyuItem
    
    
    class DouyuSpider(scrapy.Spider):
        name = 'douyu'                 # 爬虫名称
        allowed_domains = ['douyu.com']   # 爬虫的地址范围,不定义,可能会跑偏
       
        # 因为要爬取的是多个网页上的数据,所以urls是变换的,定义一个url基础地址
        baseURL = "https://www.douyu.com/api/v1/getVerticalRoom?limit=20&offset="
        offset = 0
        
        # 开始的地址为baseURl的拼接
        start_urls = [baseURL + str(offset)]
        
        # 处理数据函数
        def parse(self, response):
            """
            因为抓取的是json数据包,使用json模块对其进行格式转化成python能处理的格式
            json.load()   和本地磁盘交互
            json.loads()  处理字符串的
    
            :param response:  浏览器返回的响应数据    
            """
            # 将得到的数据通过json.loads()方法转换,返回的是一个列表,取里面的data键对应的值
            data_list = json.loads(response.body)['data']
    		
            # 判断data_list是否有值,如果没有则返回,结束爬虫程序
            if len(data_list) == 0:
                return
    		
            # 将需要的数据保存到定义好的容器里
            for data in data_list:
                item = DouyuItem()          # 创建容器对象
                item['nickname'] = data['nickname']   
                item['imagelink'] = data['vertical_src']
                
                # yield的作用相当于一个生成器,暂停函数,将数据先送走,再回来继续执行函数
                yield item      # ----将返回值传到item容器中,然后在传到管道文件中            
    		   
            	# 当本页的数据爬取完毕以后,继续下一个页面的爬取,所以需要重新设置url地址 
                self.offset += 20
                
                # 重新发起请求,Request传入两个参数,一个为新构建的url地址,callback回调函数
                yield scrapy.Request(self.baseURL + str(self.offset), callback=self.parse)
                
        # 如果url不规律,可以在继续定义paese函数
        # def parse_next(self, response):
        	pass
    
  • 书写piplines.py----管道文件 处理数据

    import os
    from .settings import IMAGES_STORE as image_store
    
    import scrapy
    from scrapy.pipelines.images import ImagesPipeline
    
    
    class DouyuPipeline(ImagesPipeline):
        # ImagesPipeline()这个类是用来下载图片用的。重写get_media_requests()函数,处理来自容器中的数据,完成后要给引擎一个提示,引擎再给下载器一个提示,继续干活。
        
        def get_media_requests(self,item,info):
            image_link = item['imagelink']
            yield scrapy.Request(image_link)
            
        # 重写item_completed(self, results, item, info),因为图片的名称保存在  参数results中,需要先将名称提取出来,在重新命名
        def item_completed(self, results, item, info):
            # results = [(True, {'url': 'https://rpic.douyucdn.cn/asrpic/191022/7188934_1304.png/dy1', 'path': 'full/7a97ea3bae91aaf7eacb629ee01494f0556cf9b6.jpg', 'checksum': 'daf0220643ec92f55054c9ccdbf779c0'})]
            # print(results)
            # print('8' * 30)
            # results[0][1]["path"]
            
            # 列表生成式,提取results中的图片名称
            path = [x["path"] for ok, x in results if ok]
    		
            # os模块重命名
            os.rename(image_store + path[0], image_store + item['nickname'] + '.jpg')
            return item
    
    
  • 配置文件settings.py

ROBOTSTXT_OBEY = False         修改君子协议

IMAGES_STORE = r"C:\Users\weichen\Desktop\spider\Douyu\Images/"  配置图片保存位置

设置请求头信息
USER_AGENT = 'Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL00 Build/HUAWEIBLA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36'                    

ITEM_PIPELINES = {
   'Douyu.pipelines.DouyuPipeline': 300,        
}                      piplines设置

启动项目:

  • 打开cmd命令行,进入Douyu目录下

    执行:  scrapy crawl douyu
    

等待爬取完毕,静静的在images目录下欣赏

总结

尝试的抓去了几次,每次的结果都不同,越到热门的时间,数据越多,可能这个数据是在线的时候才会被写入此数据包。

1、json数据基本上都python字典的类型是一样的,不过需要转换。对于优化代码量,基础就很重要了,比如列表生成式等。

2、在学习的过程中越来越发现读源码的重要性,尤其是框架,要想学会精通,熟悉框架,阅读源码是最合适的,避免重复造轮子。
3、

  • get() 返回字符串
  • extract() 返回的额是一个列表
  • extract_first() 返回的是一个字符串

你可能感兴趣的:(爬虫)