目标网站:https://www.mn52.com/

本文代码已上传至git和百度网盘,链接分享在文末

网站概览

目标,使用scrapy框架抓取全部图片并分类保存到本地。

1.创建scrapy项目

scrapy startproject images

2.创建spider

cd images
scrapy genspider mn52 www.mn52.com

创建后结构目录如下

3.定义item定义爬取字段

# -*- 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 ImagesItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
image_url = scrapy.Field()
field_name = scrapy.Field()
detail_name = scrapy.Field()

这里定义三个字段,分别为图片地址,图片类别名称和图片详细类别名称

4.编写spider

# -*- coding: utf-8 -*-
import scrapy
import requests
from lxml import etree
from images.items import ImagesItem class Mn52Spider(scrapy.Spider):
name = 'mn52'
# allowed_domains = ['www.mn52.com']
# start_urls = ['http://www.mn52.com/'] def start_requests(self):
response = requests.get('https://www.mn52.com/')
result = etree.HTML(response.text)
li_lists = result.xpath('//*[@id="bs-example-navbar-collapse-2"]/div/ul/li')
for li in li_lists:
url = li.xpath('./a/@href')[0]
field_name = li.xpath('./a/text()')[0]
print('https://www.mn52.com' + url,field_name)
yield scrapy.Request('https://www.mn52.com' + url,meta={'field_name':field_name},callback=self.parse) def parse(self, response):
field_name = response.meta['field_name']
div_lists = response.xpath('/html/body/section/div/div[1]/div[2]/div')
for div_list in div_lists:
detail_urls = div_list.xpath('./div/a/@href').extract_first()
detail_name = div_list.xpath('./div/a/@title').extract_first()
yield scrapy.Request(url='https:' + detail_urls,callback=self.get_image,meta={'detail_name':detail_name,'field_name':field_name})
url_lists = response.xpath('/html/body/section/div/div[3]/div/div/nav/ul/li')
for url_list in url_lists:
next_url = url_list.xpath('./a/@href').extract_first()
if next_url:
yield scrapy.Request(url='https:' + next_url,callback=self.parse,meta=response.meta) def get_image(self,response):
field_name = response.meta['field_name']
image_urls = response.xpath('//*[@id="originalpic"]/img/@src').extract()
for image_url in image_urls:
item = ImagesItem()
item['image_url'] = 'https:' + image_url
item['field_name'] = field_name
item['detail_name'] = response.meta['detail_name']
# print(item['image_url'],item['field_name'],item['detail_name'])
yield item

逻辑思路:spider中重写start_requests获取起始路由,这里起始路由设为图片的一级分类如性感美女,清纯美女,萌宠图片等的地址,使用requests库请求mn52.com来解析获取。然后把url和一级分类名称传递给parse,在parse中解析获取图片的二级分类地址和二级分类名称,并判断是否含有下一页信息,这里使用scrapy框架自动去重原理,所以不用再写去重逻辑。获取到的数据传递给get_image,在get_image中解析出图片路由并赋值到item字段中然后yield item.

5.pipelines管道文件下载图片

# -*- 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
import scrapy
import os
# 导入scrapy 框架里的 管道文件的里的图像 图像处理的专用管道文件
from scrapy.pipelines.images import ImagesPipeline
# 导入图片路径名称
from images.settings import IMAGES_STORE as images_store class Image_down(ImagesPipeline):
def get_media_requests(self, item, info):
yield scrapy.Request(url=item['image_url']) def item_completed(self, results, item, info):
print(results)
image_url = item['image_url']
image_name = image_url.split('/')[-1]
old_name_list = [x['path'] for t, x in results if t]
# 真正的原图片的存储路径
old_name = images_store + old_name_list[0]
image_path = images_store + item['field_name'] + '/' + item['detail_name'] + '/'
# 判断图片存放的目录是否存在
if not os.path.exists(image_path):
# 根据当前页码创建对应的目录
os.makedirs(image_path)
# 新名称
new_name = image_path + image_name
# 重命名
os.rename(old_name, new_name)
return item

分析:scrapy内置的ImagesPipeline自己生成经过md5加密的图片名称,这里导入os模块来使图片下载到自定义的文件夹和名称,需要继承ImagesPipeline类。

6.settings中设置所需参数(部分)

#USER_AGENT = 'images (+http://www.yourdomain.com)'
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36' #指定输出某一种日志信息
LOG_LEVEL = 'ERROR'
#将日志信息存储到指定文件中,不在终端输出
LOG_FILE = 'log.txt'
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
IMAGES_STORE = './mn52/' ITEM_PIPELINES = {
# 'images.pipelines.ImagesPipeline': 300,
'images.pipelines.Image_down': 301,
}

说明:settings中主要定义了图片的存储路径,user_agent信息,打开下载管道。

7.创建crawl.py文件,运行爬虫

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings process = CrawlerProcess(get_project_settings()) # mn52是爬虫名
process.crawl('mn52')
process.start()

这里没有使用cmdline方法运行程序,因为涉及到后面的打包问题,使用cmdline方法无法打包。

8.至此,scrapy爬虫已编写完毕,右键运行crawl文件启动爬虫,图片就会下载。

控制台输出:

打开文件夹查看图片

全站下载完成的话大概有22万张图片

9.打包scrapy爬虫。

scrapy爬虫作为一个框架爬虫也是可以被打包成exe文件的,是不是很神奇/

使用scrapy框架爬取图片网全站图片(二十多万张),并打包成exe可执行文件的更多相关文章

  1. scrapy框架爬取图片并将图片保存到本地

    如果基于scrapy进行图片数据的爬取 在爬虫文件中只需要解析提取出图片地址,然后将地址提交给管道 配置文件中:IMAGES_STORE = './imgsLib' 在管道文件中进行管道类的制定: f ...

  2. 将Python项目打包成EXE可执行文件(单文件,多文件,包含图片)

    解决 将Python项目打包成EXE可执行文件(单文件,多文件,包含图片) 1.当我们写了一个Python的项目时,特别是一个GUI项目,我们特备希望它能成为一个在Windows系统可执行的EXE文件 ...

  3. python爬虫---scrapy框架爬取图片,scrapy手动发送请求,发送post请求,提升爬取效率,请求传参(meta),五大核心组件,中间件

    # settings 配置 UA USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, l ...

  4. 爬虫 Scrapy框架 爬取图虫图片并下载

    items.py,根据需求确定自己的数据要求 # -*- coding: utf-8 -*- # Define here the models for your scraped items # # S ...

  5. 正则爬取京东商品信息并打包成.exe可执行程序。

    本文爬取内容,输入要搜索的关键字可自动爬取京东网站上相关商品的店铺名称,商品名称,价格,爬取100页(共100页) 代码如下: import requests import re # 请求头 head ...

  6. 正则爬取京东商品信息并打包成.exe可执行程序

    本文爬取内容,输入要搜索的关键字可自动爬取京东网站上相关商品的店铺名称,商品名称,价格,爬取100页(共100页) 代码如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 ...

  7. 使用scrapy框架爬取自己的博文(2)

    之前写了一篇用scrapy框架爬取自己博文的博客,后来发现对于中文的处理一直有问题- - 显示的时候 [u'python\u4e0b\u722c\u67d0\u4e2a\u7f51\u9875\u76 ...

  8. Python多线程爬图&Scrapy框架爬图

    一.背景 对于日常Python爬虫由于效率问题,本次测试使用多线程和Scrapy框架来实现抓取斗图啦表情.由于IO操作不使用CPU,对于IO密集(磁盘IO/网络IO/人机交互IO)型适合用多线程,对于 ...

  9. 使用scrapy框架做赶集网爬虫

    使用scrapy框架做赶集网爬虫 一.安装 首先scrapy的安装之前需要安装这个模块:wheel.lxml.Twisted.pywin32,最后在安装scrapy pip install wheel ...

随机推荐

  1. springIOC源码接口分析(四):MessageSource

    一 定义方法 MessageSource接口用于支持信息的国际化和包含参数的信息的替换 这个接口定义了三个方法: public interface MessageSource { /** * 解析co ...

  2. mybatis从数据库中取数据且分组,返回分组数据

    mapper.xml文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PU ...

  3. java字符编码-Unicode编码问题刨根究底

    博客搬家: java字符编码问题 前段时间在读<java核心技术卷一>,遇到一些名词:码点.代码单元等,其实字面意思不难理解,解释如下 码点(code point):Unicode编码表中 ...

  4. [travis-ci]自动集成测试

    自动运行测试的平台https://travis-ci.org/ 可以自动导入测试github上的项目 因为yml文件格式错误会导致找不到配置文件, 这里要注意啦, 掉坑里了.... https://d ...

  5. re模块 findall()详解

    1. findall() 函数的2种表示形式 import re kk = re.compile(r'\d+') kk.findall('one1two2three3four4') #[1,2,3,4 ...

  6. CodeIgniter框架使用总结

    CodeIgniter框架 1.回忆MVC 1.1.M:模型,提供数据,保存数据 1.2.V:视图,只负责显示,表单form 1.3.C:控制器,协调模型和视图 1.4.action:动作,是控制器中 ...

  7. 【python-leetcode713-双指针】乘积小于k的子数组

    问题描述: 给定一个正整数数组 nums. 找出该数组内乘积小于 k 的连续的子数组的个数. 示例 1: 输入: nums = [10,5,2,6], k = 100输出: 8解释: 8个乘积小于10 ...

  8. mount.nfs: Stale file handle的解决方法

    在NFS客户端挂载rpc共享服务的时候出现这个问题 # mount -t nfs 192.168.20.6:/data /mnt mount.nfs: Stale file handle 原因是当cl ...

  9. [Redis-CentOS7]Redis数据持久化(八)

    配置文件位置 /ect/redis.conf RDB存储配置 save 900 1 # 900秒之内发生一次写操作保存 save 300 10 # 300秒内写10次保存 save 60 10000 ...

  10. H5页面长按复制功能实现

    手机赚钱怎么赚,给大家推荐一个手机赚钱APP汇总平台:手指乐(http://www.szhile.com/),辛苦搬砖之余用闲余时间动动手指,就可以日赚数百元 默认情况下禁止了长按复制功能,要此功能需 ...