爬虫思路:先拼接json数据包的url,再从中提取图片链接
- import scrapy
-
- #定义数据结构:图片链接+图片名称
- class SoItem(scrapy.Item)
-
- img_link = scrapy.Field()
- #图片名称,用于给下载下来的图片命名
- img_title = scrapy.Field()
- import scrapy
- import json
- from ..items import SoItem
-
- class SoSpider(scrapy.Spider):
- name = 'so'
- allowed_domains = ['image.so.com']
-
- #图片的json数据包的url
- url = 'https://image.so.com/zjl?ch=beauty&t1=595&src=banner_beauty&gid=fc8d902e79ef72ded26b6b625909538b&sn={}&listtype=new&temp=1'
-
- #重写scrapy.Spider的start_requests方法,因为一次性给调度器多个链接
- def start_requests(self):
- #拼个5个图片的数据包的url
- for sn in range(0,121,30):
- url = self.url.format(sn):
-
- #将网页交给调度器
- yield = scrapy.Request(url=url,callback=self.parse)
-
- #解析函数,提取图片链接
- def parse(self,response):
- #拿响应内容
- html = json.loads(response.text)
- #从items.py中导入item,将每个图片的链接和名字赋值给item,并传给管道
- item = SoItem()
- for img in html['list']: #html['list']为所有列表的信息
- #向item中赋值并传给管道文件
- item['img_link'] = img['qhimg_url'] #单个图片的链接
- item['img_title'] = img['title']
-
- #将item传给管道文件
- yield item
pipelines.py中
- import scrapy
- #导入scrapy提供的图片管道类,实现下载图片功能
- #功能封装了爬虫文件中:为了保存下来图片,将图片链接发给调度器入队列,再指定解析函数,然后再得到response.body,然后再with open文件保存下来的步骤
- from scrapy.pipelines.images import ImagesPipeline
-
- class SoPipeline(ImagesPipeline):
- #重写ImagePipeline类的get_media_requests方法
- #该方法用于将图片链接scrapy.Request传给调度器
- def get_media_requests(self,item,info):
- yield scrapy.Request(
- url=item['img_link'],
- meta={'name':item['img_title']} #将图片名通过item传给管道
- )
- #接下来下载图片保存图片的功能已被封装
-
- #源码默认将下载的文件名用hashlib.sha1加密,并放在一个full文件夹下
- #我们想用文件名title给下载下来的图片命名,并且去掉full文件夹,所以需要重写方法:file_path()
- def file_path(self,request,respnse=None,info=None):
- #scrapy.Request()中所有参数都为请求对象requests的属性(可以将这两个看成一样)
- name = request.meta['name']
- #拼接图片名
- filename = name + '.' + request.url.split('.')[-1] #request.url.split('.')[-1]为图片的格式(jpg,png等)
- return filename
-
- #打印出数据的管道类
- class SoPipeline(object):
- def process_item(self,item,spider):
- print(item['img_link'])
- return item
settings.py中
- ROBOTSTXT_OBEY = False
- DOWNLOAD_DELAY = 0.1
- DEFAULT_REQUEST_HEADERS = {
- 'Accept':'...',
- 'Accept-Language':'..',
- 'User-Agent':'...'
- }
- ITEM_PIPELINES = {
- 'So.pipelines.SoPipeline': 300,
- }
-
- #指定图片(非结构化数据)保存的路径
- IMAGES_STORE = '/home/ubuntu/360_images/'
主项目目录下创建run.py
- from scrapy import cmdline
-
- cmdline.execute('scrapy crawl so'.split())
知识点扩展
如果以后要抓文件,scrapy的管道文件中也帮你封装了下载保存的方法,步骤如下:
pipelines.py中
- from scrapy.pipelines.files import FilePipeline
-
- class SoPipeline(FilePipeline):
- #要重写的方法也和图片一样
- ...
settings.py中
- #指定文件保存的路径
- FILES_STORE = '/home/...'