我们要爬取的网站为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. android开发内存优化之软引用

    所有Android的开发者一定都遇到过内存溢出这个头疼的问题,一旦出现这个问题,很难直接确定我们的应用是那里出了问题,要想定位问题的原因,必须通过一些内存分析工具和强大的经验积累才能快速的定位到问题具 ...

  2. json 登陆协议分析

    登录方式有两种:1)用户名密码登陆,code 为 5401 (2) IMSI和TOKEN 登陆, code 为93 POST /tcpbus/mobile HTTP/1.1Host: clientac ...

  3. NET分页实现及代码

    最近在写一个关于NET的框架,写到后面果不其然的就遇到了分页,自己看了很多关于分页的并自己结合写了一个,晒出来和大家分享一下,第一次写博客望大家多多提意见啦... cs文件分页代码: Paging p ...

  4. C# DataGridView添加右键菜单的简单应用

    首先,参考了下以下文章: https://blog.csdn.net/qin_zhangyongheng/article/details/23773757 感谢. 项目中要在DataGridView中 ...

  5. 忽略warning 警告

    1

  6. 标题title出现不规则背景

    Html代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  7. form在模版中的渲 染方式

    链接:https://www.jianshu.com/p/46b2aa2d5a23 form.as_p 渲染表单为一系列的p标签,每个p标签包含一个字段: <p> <label fo ...

  8. 正则表达式,sed简单用法

      一. 正则表达式 1. 常见的正则表达式字符 [] 匹配字符集 grep "bl[lo]g" oldboy.txt 表示字符‘l’或者‘o’都可匹配 * 重复前面字符任意次 g ...

  9. 浅谈Android选项卡(一)

    选项卡,这样UI设计在很多方面都存在,window,web,ios,Android. 选项卡的主要作用,不用多介绍,可以在有线的空间内,显示出更多内容,同时也是操作起来也很方便.

  10. leetcode-137-Single Number II-第二种解法

    题目描述: 详细的题目描述见上一篇博客<leetcode-137-Single Number II-第一种解法>,这里简单说一下. 有一个数组,所有元素都出现了三次,除了一个元素只出现了一 ...