scrapy框架 crawl spider 爬取.gif图片

创建项目:
scrapy startproject qiumeimei
建立爬虫应用:
scrapy genspider -t crawl meimei www.qiumeimei.com

爬虫文件 meimei.py 源代码 开始 :

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from qiumeimei.items import QiumeimeiItem
class MeimeiSpider(CrawlSpider):
    name = 'meimei'     #爬虫的名字跟重要
    # allowed_domains = ['www.qiumeimei.com']
    start_urls = ['http://www.qiumeimei.com/tag/gif']    #爬取的第一个url
    rules = (
                                    # 写入正则表达式,拿出页面里的能匹配到的所有a连接,在重新调用   parse_item方法   
        Rule(LinkExtractor(allow=r'http://www.qiumeimei.com/tag/gif/page/\d+'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        print("我到这儿了!!!")
        # 截取路由,拿出page(页码)   response.url = http://www.qiumeimei.com/tag/gif/page/2
        img_page = response.url.split('/')[-1]    
        if img_page=='gif':    #因为第一页的路由是    http://www.qiumeimei.com/tag/gif
            img_page = "1"
        div_list = response.xpath('//div[@class="home_main_wrap"]/div')
        for div in div_list:
            item = QiumeimeiItem()
            # 图片名字
            img_name = div.xpath('./div/h2/a/text()').extract_first()
            if img_name:
                item['img_name'] = img_name
            # 图片的url     (不要被页面的伪装所有迷惑,找到正确的url)
            img_url = div.xpath('./div/p/img/@data-lazy-src').extract_first()
            if img_url:
                item['img_url'] = img_url
            item['img_page'] = img_page
            yield item

爬虫文件 meimei.py 源代码 结束。

items 定义字段名称 源代码 开始:

import scrapy
class QiumeimeiItem(scrapy.Item):
    # define the fields for your item here like:
    # 定义存储的字段名称
    img_name = scrapy.Field()
    img_url = scrapy.Field()
    img_page = scrapy.Field()

The most important!!! 管道文件 pipelines.py

import scrapy
import os
from scrapy.utils.misc import md5sum
# 导入scrapy 框架里的 管道文件的里的图像 图像处理的专用管道文件
from scrapy.pipelines.images import ImagesPipeline
# 前提必须在settings.py 文件里定义一个文件的存放位置,然后引进来
from qiumeimei.settings import IMAGES_STORE as images_store

# 必须继承父类 ImagesPipeline
class QiumeimeiPipeline(ImagesPipeline):
    # 重写父类的下载图片的方法
    def get_media_requests(self, item, info):
        # print(item['img_url'],item['img_page'],item['img_name'])
        # 自动请求图片的url,转换为二进制下载
        yield scrapy.Request(url=item['img_url'])


        # 建立分级文件夹的方法
    def item_completed(self, results, item, info):
        page = item['img_page']   #第几页
        img_name = item['img_name']     #图片的名称
        print(f"当前正在下载第<<<{page}>>>页的图片")

        # 新的图片存放位置
        img_NEWpath = images_store + page + '/'    #"./images/2/"
        # 老的文件夹存放位置(也就是不定义文件夹的时候,自动存放的位置)
        # 列表推导式   (详细介绍,会在以后的发表里~~~)
        old_path_list = [x['path'] for t,x in results if t]
        # 真正的图片存放位置
        old_path = images_store + old_path_list[0]    #"./images/full/meimei.gif"  (自动创建的full文件夹)
            # 建立文件夹
        if not os.path.exists(img_NEWpath):
            os.mkdir(img_NEWpath)
        # 图片名字(图片的相对路径)
        new_name = img_NEWpath + img_name + ".gif"     #"./images/2/妹妹.gif"
        # 替换图片的名字,(也就是替换存放图片的位置)
        # print("图片老名字是%s------图片新名字是%s"%(old_path,new_name))
        os.rename(old_path,new_name)
        return item


    # 重写下载规则(有点深奥,本人暂时没看懂,哪位大神看懂了,还请评论下方留言,指点一二,我当感激不尽!!!)
    def image_downloaded(self, response, request, info):
        checksum = None
        for path, image, buf in self.get_images(response, request, info):
            if checksum is None:
                buf.seek(0)
                checksum = md5sum(buf)
            width, height = image.size
            if self.check_gif(image):
                self.persist_gif(path, response.body, info)
            else:
                self.store.persist_file(
                    path, buf, info,
                    meta={'width': width, 'height': height},
                    headers={'Content-Type': 'image/jpeg'})
        return checksum

    def check_gif(self, image):
        if image.format is None:
            return True

    def persist_gif(self, key, data, info):
        root, ext = os.path.splitext(key)
        absolute_path = self.store._get_filesystem_path(key)
        self.store._mkdir(os.path.dirname(absolute_path), info)
        f = open(absolute_path, 'wb')  # use 'b' to write binary data.
        f.write(data)

管道文件源代码 结束!!!

settings.py 配置文件 源代码 开始

定义图片的存放位置(随意位置):

                  IMAGES_STORE = './images/'

伪装浏览器:

 USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'

修改是否遵守 robots协议

                  ROBOTSTXT_OBEY = False

去除不重要的日志信息,加上底下两句话(随意位置):

LOG_LEVEL = 'ERROR'    #只看见报错的信息
LOG_FILE = 'log.txt'   #可以自动的创建一个log.txt文件,把报错的信息存入里面。

千万不要忘了打开管道文件的设置 (开关)!!!

ITEM_PIPELINES = {
   'qiumeimei.pipelines.QiumeimeiPipeline': 300,
}

好了,,settings.py 文件 源代码 结束

最后运行文件:

scrapy crawl meimei --nolog

下面图片就是我下载后的:真的会动哦!!!
scrapy框架 crawl spider 爬取.gif图片_第1张图片

对了最底下的那个start.py 文件是运行爬虫的快捷方式,这样就不用一直输命令行了、代码就短短的两句话。

from scrapy import cmdline
# ()里存储执行的命令行  ,因为是字符串,所有截取一下空格,cmd才认识
cmdline.execute("scrapy crawl meimei --nolog".split())

scrapy框架 crawl spider 爬取.gif图片_第2张图片 这就是下载后的储存方式

对了,,还有图片呢:
算了,,,有点不方便,,,嘿嘿,,自己下载慢慢看吧!!!

你可能感兴趣的:(Python爬虫实战,爬虫,scrapy,爬虫实战,简单爬虫,经典爬虫实战演练)