我们要爬取的网站为http://image.so.com/z?ch=photography,打开开发者工具,页面往下拉,观察到出现了如图所示Ajax请求,

其中list就是图片的详细信息,接着观察到每个Ajax请求的sn值会递增30,当sn为30时,返回前30张图片,当sn为60时,返回第31到60张图片,所以我们每次抓取时需要改变sn的值。接下来实现这个项目。

首先新建一个项目:scrapy startproject images360

新建一个Spider:scrapy genspider images images.so.com

在settings.py中定义爬取的最大量:MAX_PAGE=10

定义一个Item以接收Spider返回的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 ImageItem(scrapy.Item):
collection = table = 'images'
id = scrapy.Field()
url = scrapy.Field()
title = scrapy.Field()
thumb = scrapy.Field()

修改images.py:

# -*- coding: utf-8 -*-
import scrapy
from scrapy import Spider,Request
from urllib.parse import urlencode
import json
from images360.items import ImageItem class ImagesSpider(scrapy.Spider):
name = 'images'
allowed_domains = ['images.so.com']
start_urls = ['http://images.so.com/'] def start_requests(self):
data = {'ch':'photography','listtype':'new'}
base_url = 'https://image.so.com/zj?'
for page in range(1,self.settings.get('MAX_PAGE')+1):
data['sn'] = page * 30
params = urlencode(data)
url = base_url + params
yield Request(url,self.parse) def parse(self, response):
result = json.loads(response.text)
for image in result.get('list'):
item = ImageItem()
item['id'] = image.get('imageid')
item['url'] = image.get('qhimg_url')
item['title'] = image.get('group_title')
item['thumb'] = image.get('qhimg_thumb_url')
yield item

利用urlencode()方法将data转化为URL的get参数,每次爬取30张图片直到爬取完成。

修改settings.py中ROBOTSTXT_OBEY变量为False,这个变量代表是否遵守网站的爬取规则,若不修改则无法爬取。

接下来我们要把爬取到的数据存入数据库,新建数据库以及表的操作在此不再赘述。创建好数据库及表后,我们需实现一个Item Pipeline以实现存入数据库的操作:

# -*- 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 from scrapy import Request
from scrapy.exceptions import DropItem
import pymysql class MysqlPipeline():
def __init__(self,host,database,user,password,port):
self.host = host
self.database = database
self.user = user
self.password = password
self.port = port @classmethod
def from_crawler(cls,crawler):
return cls(
host=crawler.settings.get('MYSQL_HOST'),
database=crawler.settings.get('MYSQL_DATABASE'),
user=crawler.settings.get('MYSQL_USER'),
password=crawler.settings.get('MYSQL_PASSWORD'),
port=crawler.settings.get('MYSQL_PORT'),
) def open_spider(self,spider):
self.db = pymysql.connect(self.host,self.user,self.password,
self.database,charset='utf8',port=self.port)
self.cursor = self.db.cursor() def close_spider(self,spider):
self.db.close() def process_item(self,item,spider):
data = dict(item)
keys = ', '.join(data.keys())
values = ', '.join(['%s'] * len(data))
sql = 'insert into %s (%s) value (%s)' %(item.table,keys,values)
self.cursor.execute(sql,tuple(data.values()))
self.db.commit()
return item

这里需要在settings.py中添加几个关于MySQL配置的变量,如下所示:

MYSQL_HOST = 'localhost'
MYSQL_DATABASE = 'images360'
MYSQL_PORT = 3306
MYSQL_USER = 'root'
MYSQL_PASSWORD = '123456'

scrapy提供了专门处理下载的Pipeline。首先定义存储文件的路径,在settings.py中添加:IMAGES_STORE = './images'

定义ImagePipeline:

# -*- 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 from scrapy import Request
from scrapy.exceptions import DropItem
from scrapy.pipelines.images import ImagesPipeline
import pymysql class ImagePipeline(ImagesPipeline):
def file_path(self,request,response=None,info=None):
url = request.url
file_name = url.split('/')[-1]
return file_name def item_completed(self,results,item,info):
image_paths = [x['path'] for ok,x in results if ok]
if not image_paths:
raise DropItem('Image Downloaded Failed')
return item def get_media_requests(self,item,info):
yield Request(item['url']) class MysqlPipeline():
def __init__(self,host,database,user,password,port):
self.host = host
self.database = database
self.user = user
self.password = password
self.port = port @classmethod
def from_crawler(cls,crawler):
return cls(
host=crawler.settings.get('MYSQL_HOST'),
database=crawler.settings.get('MYSQL_DATABASE'),
user=crawler.settings.get('MYSQL_USER'),
password=crawler.settings.get('MYSQL_PASSWORD'),
port=crawler.settings.get('MYSQL_PORT'),
) def open_spider(self,spider):
self.db = pymysql.connect(self.host,self.user,self.password,
self.database,charset='utf8',port=self.port)
self.cursor = self.db.cursor() def close_spider(self,spider):
self.db.close() def process_item(self,item,spider):
data = dict(item)
keys = ', '.join(data.keys())
values = ', '.join(['%s'] * len(data))
sql = 'insert into %s (%s) value (%s)' %(item.table,keys,values)
self.cursor.execute(sql,tuple(data.values()))
self.db.commit()
return item

get_media_requests()方法取出Item对象的URL字段,生成Request对象发送给Scheduler,等待执行下载。

file_path()方法返回图片保存的文件名。

item_complete()方法当图片下载成功时返回Item说明下载成功,否则抛出DropItem异常,忽略这张图片。

最后需在settings.py文件中设置ITEM_PIPELINES以启动item管道:

ITEM_PIPELINES = {
'images360.pipelines.ImagePipeline': 300,
'images360.pipelines.MysqlPipeline': 301
}

大功告成,现在可以进行爬取了~输入scrapy crawl images即可完成爬取。

Scrapy框架学习(四)爬取360摄影美图的更多相关文章

  1. 基于scrapy框架输入关键字爬取有关贴吧帖子

    基于scrapy框架输入关键字爬取有关贴吧帖子 站点分析 首先进入一个贴吧,要想达到输入关键词爬取爬取指定贴吧,必然需要利用搜索引擎 点进看到有四种搜索方式,分别试一次,观察url变化 我们得知: 搜 ...

  2. 一个scrapy框架的爬虫(爬取京东图书)

    我们的这个爬虫设计来爬取京东图书(jd.com). scrapy框架相信大家比较了解了.里面有很多复杂的机制,超出本文的范围. 1.爬虫spider tips: 1.xpath的语法比较坑,但是你可以 ...

  3. scrapy框架综合运用 爬取天气预报 + 定时任务

    爬取目标网站: http://www.weather.com.cn/ 具体区域天气地址: http://www.weather.com.cn/weather1d/101280601.shtm(深圳) ...

  4. Scrapy 框架 使用 selenium 爬取动态加载内容

    使用 selenium 爬取动态加载内容 开启中间件 DOWNLOADER_MIDDLEWARES = { 'wangyiPro.middlewares.WangyiproDownloaderMidd ...

  5. Scrapy框架——使用CrawlSpider爬取数据

    引言 本篇介绍Crawlspider,相比于Spider,Crawlspider更适用于批量爬取网页 Crawlspider Crawlspider适用于对网站爬取批量网页,相对比Spider类,Cr ...

  6. <scrapy爬虫>爬取360妹子图存入mysql(mongoDB还没学会,学会后加上去)

    1.创建scrapy项目 dos窗口输入: scrapy startproject images360 cd images360 2.编写item.py文件(相当于编写模板,需要爬取的数据在这里定义) ...

  7. 爬虫学习(二)--爬取360应用市场app信息

    欢迎加入python学习交流群 667279387 爬虫学习 爬虫学习(一)-爬取电影天堂下载链接 爬虫学习(二)–爬取360应用市场app信息 代码环境:windows10, python 3.5 ...

  8. 萌新学习Python爬取B站弹幕+R语言分词demo说明

    代码地址如下:http://www.demodashi.com/demo/11578.html 一.写在前面 之前在简书首页看到了Python爬虫的介绍,于是就想着爬取B站弹幕并绘制词云,因此有了这样 ...

  9. scrapy框架学习

    一.初窥Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 其最初是为了 页面抓取 (更确切来说, 网 ...

随机推荐

  1. IntelliJ OpenCV 开发环境搭建

    Windows下的IntelliJ + OpenCV开发环境搭建 基于IntelliJ IDEA 15 和 OpenCV 3.1.0 1. 在OpenCV官网下载OpenCV安装程序,双击解压到目标目 ...

  2. ASP.NET MVC ActionFilterAttribute用法

  3. C#连接MySql数据库代码

    之前学JAVA的时候,老师讲数据库的时候,讲到可以用一个类来连接数据库,叫做Dao层,今天要用C#做上位机,也有一些数据要写到数据库中去,我就想,能不能也给C#写一个这样的Dao层来连接数据库,我就去 ...

  4. libz.dylib框架怎么导入

    1.General下 2.点击+号在弹出的对话框选择addother 3.在弹出的对话框中输入"cmd"+"shift"+"g" 输入/us ...

  5. “全栈2019”Java第五十三章:向上转型和向下转型详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. 修复已损坏的交换机IMG

    1.找出与当前交换机匹配的升级镜像以及合适的BOOT启动程序(这要通过渠道获取) 2.搭建 TFTP 服务器. 3.启动交换机,链接console线缆 4.在 BOOT 模式,完成一下操作 1.配置I ...

  7. docker安装mysql57

    提升应用交付效率 1. 支持服务发现,避免服务重启迁移 IP 变更带来影响:2. 支持微服务化,降低代码维护及重构复杂度,适应快速变化的业务需求. 快速响应业务变化 1. 灵活水平扩展,应对业务量的骤 ...

  8. Git的一些用法(下)

    (4) 提交分支 提交分支命令 : 将本地的分支提交到 GitHub中; git push origin experiment (5) 分支合并移除 合并分支命令 : 合并分支之后, 分支中有的文件在 ...

  9. __getitem__

    如果在类中定义了__getitem__()方法,那么他的实例对象(假设为P)就可以这样P[key]取值.当实例对象做P[key]运算时,就会调用类中的__getitem__()方法.

  10. 在eclips中配置maven

    可参考https://jingyan.baidu.com/article/59703552cb9b988fc00740a4.html