站长素材网 图标信息爬取(scrapy)

准备工作:

    1.创建scrapy项目

        cmd命令行(若想创建至桌面,可先 cd desktop) 输入 scrapy startproject +项目名 ,enter根据命令行显示示例依次操作即可

        用pycharm打开创建的文件夹,并创建debug.py文件,方便断点调试程序

        debug文件内代码

#coding:utf-8
from scrapy.cmdline import execute
execute(['scrapy','crawl','爬虫名'])

代码块:

    1.主要代码

# -*- coding: utf-8 -*-
import scrapy
# 引入数据模型类
from ..items import ImgItem

class SucaiSpider(scrapy.Spider):
    name = 'sucai'
    allowed_domains = ['sc.chinaz.com']
    start_urls = ['http://sc.chinaz.com//']

    def parse(self, response):
        # 200 OK 请求成功
        # 302 重定向
        # 404 url地址不存在
        # 403 没有权限访问,服务器拒绝连接
        # 5XX 服务器的错误
        # 找到图标的链接
        tb_href = response.xpath('//div[@class="nav"]/ul/li[@class="nos"]/a[3]/@href').extract_first('')
        # 拼接完整的url
        tb_url = 'http://sc.chinaz.com'+tb_href
        # 发送一个请求
        # 1.url请求的地址 2.callback 回调函数 默认调用parse()
        yield scrapy.Request(
            url=tb_url,
            callback=self.parse_list
        )

    # 解析所有图标列表
    def parse_list(self,response):
        # 根据xpath找到所有图标详情页的地址
        detail_links = response.xpath('//ul[@class="pngblock imgload"]/li/p/a/@href').extract()

        # for循环遍历列表,取出每一个图片的详细地址,发起请求
        for link in detail_links:
            yield scrapy.Request(
                url=link,
                # 请求成功了,调用parse_detail解析详情
                callback=self.parse_detail,
                # 用于请求数据时,携带一些额外的参数
                # meta={'hello':'world'}
            )
        # 找到下一页的链接
        next_href = response.xpath('//a[@class="nextpage"]/@href').extract_first('')
        # 判断是否有下一页
        if next_href:
            # 拼接下一页的地址
            next_url = 'http://sc.chinaz.com/tubiao/'+next_href
            yield scrapy.Request(
                url=next_url,
                callback=self.parse_list
            )

    # 解析详情页中的每一张图片地址
    def parse_detail(self,response):

        # 解析图片分类名称
        categray = response.xpath('//h2/a/text()').extract_first('')

        # 解析图片地址
        imgs_src = response.xpath('//div[@class="png_pic"]/img/@src').extract()

        # for循环遍历所有图片的详细地址
        for src in imgs_src:
            # 创建数据模型对象
            img = ImgItem()
            # src图片下载地址必须放在列表中
            img['src'] = [src]
            # 图片分类
            img['categray'] = categray
            yield img



    2. pipelines.py

    

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
# 引入scrapy自带的图片下载类
from scrapy.pipelines.images import ImagesPipeline
# 引入scrapy
import scrapy

class SucaiSpiderPipeline(object):
    def process_item(self, item, spider):
        return item


# 1.下载图片  2.指定图片存放目录
# 继承于scrapy自带的图片下载类
class MyImagePipeline(ImagesPipeline):

    # 获取图片下载请求的函数
    def get_media_requests(self, item, info):

        # 1.取出图片下载的url地址
        url = item['src'][0]
        # 2.根据url地址创建请求对象
        request = scrapy.Request(
            url=url,
            # 利用meta将item传递到file_path函数中
            meta={"item":item}
        )
        # 最终返回一个下载图片的请求对象的列表
        return [request]

    # 重写file_path指定图片存放路径
    def file_path(self, request, response=None, info=None):
        # 根据key取出meta中的item,这个item中包含的就是下载图片的数据
        item = request.meta['item']
        # 取出分类
        categray = item['categray']
        # 取出图片下载地址
        src = item['src'][0]
        # 分割获取图片名称
        name = src.split('/')[-1]

        # 最终只需要将图片的存放路径和图片的名称返回即可
        return '%s/%s'%(categray, name)

    3. items.py

    

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class SucaiSpiderItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pass


# 新建图片的数据模型
class ImgItem(scrapy.Item):
    # 图标的下载地址
    src = scrapy.Field()
    # 图标的分类
    categray = scrapy.Field()
settings.py 自己做相应配置即可

        

你可能感兴趣的:(Python,python,scrapy,图标下载)