我们要爬取的网站为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. Redis 工具类

    项目里的Redis 工具类,写下来以备后用 public class RedisConnector { public class RedisParseResult<T> { public ...

  2. codeforces|CF1054D Changing Array

    因为数据范围是2e5级别的,所以我们考虑用异或前缀和来处理区间的异或情况.(比如说a包括b,那么我们通过异或可以知道b对于a的补区间的信息) 之后因为对任意\(a_i\)进行取反操作,会改变它和它之后 ...

  3. depth深度

    du.tree.find ls -li find ./ -inum 1193220 | while read a ;do rm -f $a;done find ./ -size 0b -type f ...

  4. jquery源码解析:pushStack,end,ready,eq详解

    上一篇主要讲解了jQuery原型中最重要的方法init.接下来再讲一些比较常用的原型方法和属性 core_slice = [].slice, jQuery.fn = jQuery.prototype ...

  5. 模块sys, os, glob, pickle, subprocess常见用法

    参考python常用标准库 http://blog.51cto.com/lizhenliang/1872538 一. sys   1. sys.argv 脚本名1.py, 命令行中执行python 1 ...

  6. Tomcat入门级小白教程

    Tomcat 类似与一个apache的扩展型,属于apache软件基金会的核心项目,属于开源的轻量级Web应用服务器,是开发和调试JSP程序的首选,主要针对Jave语言开发的网页代码进行解析,Tomc ...

  7. spring IOC的实现原理

    姓名:陈中娇     班级:软件151 1. IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化.定位.配置应用程序中的对象及建立这些对象间的依赖.应用程序无需直接在代码中new相关的对象,应 ...

  8. String字符串补位

    String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的读者应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重载形式. l    ...

  9. 动态树Link-cut tree(LCT)总结

    动态树是个好玩的东西 LCT题集 预备知识 Splay 树链剖分(好像关系并不大) 动态树(Link-cut tree) 先搬dalao博客 什么是LCT? 动态树是一类要求维护森林的连通性的题的总称 ...

  10. centos文件查找命令

    在使用linux时,经常需要进行文件查找.其中查找的命令主要有find和grep.两个命令是有区的. 区别:(1)find命令是根据文件的属性进行查找,如文件名,文件大小,所有者,所属组,是否为空,访 ...