Scrapy抓站:大批量下载360指定专题下的照片并保存到sql和本地文件夹下
目标网站:http://images.so.com/ (摄影专栏)
Scrapy抓站:360照片
- 1. 新建项目
- 2. 新建Spider
- 3. 分析目标网站的种种
- 4. 构造请求
- 5. 定义提取信息的字段
- 6. 编写 Spider 方法
- 7. 存储信息
- 7.1 Mysql保存
- 7.2 本地文件保存
- 8. 执行程序
- 9. 最终的效果图
1. 新建项目
scrapy startproject images360(名目名)
2. 新建Spider
直接用Pycharm打开上一步所创建的项目,在最下面的Terminal处执行该命令:
scrapy genspider images images.so.com
3. 分析目标网站的种种
- 进入目标网站所要爬取的摄影专题的页面下
- 下拉滚动栏查看图片,显而易见可知是Ajax请求数据的方式,我以前的博客中有对该请求方式的详细说明,f12直接查看XHR下的请求信息:
可以看到请求方式是GET方式,其是带有参数的请求方式,分析参数得:
ch指所选的专题名称,sn指该页显示30张图片,listtype指一种排序方式,temp指不知名参数,可变参数只有sn,所以该参数作为翻页更新请求的突破点。 - 查看数据所在地及其返回格式:
可得数据返回格式为JSON,很好处理。
4. 构造请求
在 images.py 文件下重写定义 start_requests() 方法:
# 此方法用于生成初始请求,它必须返回一个迭代的对象。# 此方法会默认使用 start_urls 中的URL来构造 Request,而且 Request 是GET请求方式# 若启动时以 POST 请求方式来访问某个站点,可以直接重写这个方法,发送 POST请求时,使用 FormRequest 即可def start_requests(self):# 设置请求头,因为之 get 请求,其请求参数跟在 url 地址后 ,可以这样设置data = {'ch':'photography','listtype':'new'}base_url = 'https://image.so.com/zjl?'# 生成 50 次的请求for page in range(1,self.settings.get('MAX_PAGE')+1):data['sn'] = page * 30# 使用 urlencode() 方法,将字典转换为 url 的 GET 参数params = urlencode(data)url = base_url + paramsprint(url)yield Request(url,self.parse)
在 setting.py 中定义最大爬取页数的变量,以及修改 ROBOTSTXT_OBEY 的值:
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
# 爬取的页数
MAX_PAGE = 50
5. 定义提取信息的字段
修改 Item.py ,定义自己的字段类:
import scrapy
from scrapy import Fieldclass ImageItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()collection = table = 'images'# 照片的 idid = Field()# 照片类型pic_desc = Field()# 照片地址url = Field()# 照片名字title = Field()# 照片缩略图thumb = Field()
6. 编写 Spider 方法
修改 images.py ,重写 parse() 方法:
def parse(self, response):result = json.loads(response.text)for image in result.get('list'):item = ImageItem()item['id'] = image.get('id')item['pic_desc'] = image.get('pic_desc')item['title'] = image.get('title')item['url'] = image.get('qhimg_url')item['thumb'] = image.get('qhimg_thumb')yield item
7. 存储信息
7.1 Mysql保存
执行该功能的是 Item Pipeline 项目管道,所以在 pipelines.py 中重写方法并配置连接数据库的相关信息:
- 建立数据库,表,字段等信息
- 实现自己 PymysqlPipeline
class PymysqlPipeline(object):#连接数据库def __init__(self):self.connect = pymysql.connect(host = 'localhost',database = 'image_360',user = 'root',password = '123456',charset = 'utf8',port = 3306)# 创建游标对象self.cursor = self.connect.cursor()# 此方法是必须要实现的方法,被定义的 Item Pipeline 会默认调用这个方法对 Item 进行处理def process_item(self,item,spider):cursor = self.cursorsql = 'insert into image_information(id,pic_desc,title,url,thumb) values (%s,%s,%s,%s,%s)'cursor.execute(sql,(item['id'],item['pic_desc'],item['title'],item['url'],item['thumb']))# 提交数据库事务self.connect.commit()return item
7.2 本地文件保存
同样在 pipelines.py 添加如下的代码即可:
# 文件下载和图片下载,支持异步和多线程
class ImagePipeline(ImagesPipeline):# 该方法返回保存的每张图片的名字def file_path(self, request, response=None, info=None):url = request.urlfile_name = url.split('/')[-1]return file_name# 单个 Item 完成下载时的处理方法,并不是每张图片都可以下载成功,所以如果某张图片下载失败就不需要保存到数据库def item_completed(self, results, item, info):image_path = [x['path'] for ok,x in results if ok]if not image_path:raise DropItem('Image Downloaded Failed')return itemdef get_media_requests(self, item, info):yield Request(item['url'])
8. 执行程序
在最下面的Terminal处执行该命令:
scrapy crawl images
9. 最终的效果图
以上就是整个的流程,比昨天有学到的新东西。
Scrapy抓站:大批量下载360指定专题下的照片并保存到sql和本地文件夹下相关推荐
- Excel记录指定文件夹下的所有文件名;批量解压压缩包,处理压缩包套压缩包问题;
10.20 发现一个问题: 当压缩包过大,文件条目超过1048576时,rarfile库中的代码已经不能解决这个压缩包了,需要加装unrar库(from unrar import rarfile)和u ...
- 使用git下载项目到本地,指定本地文件夹位置的三种方式
使用git下载项目到本地,指定本地文件夹位置的三种方式 使用VSCODE里的"克隆"功能直接粘贴项目链接即可选择本地想保存的位置. 使用git bash窗口下载项目之前,先切换到你 ...
- python下载文件到指定文件夹-python实现指定文件夹下的指定文件移动到指定位置...
# coding:utf-8 import os import shutil import sys reload(sys) sys.setdefaultencoding('utf8') # print ...
- python下载文件到指定目录-Python获取指定文件夹下的文件名的方法
本文采用os.walk()和os.listdir()两种方法,获取指定文件夹下的文件名. 一.os.walk() 模块os中的walk()函数可以遍历文件夹下所有的文件. os.walk(top, t ...
- xml遍历文件夹vector_怎么统计指定文件夹下含有.xml格式的文件数目
如何统计指定文件夹下含有.xml格式的文件数目?如题 ------解决思路----------------------Directory.GetFiles(@"路径", " ...
- VB得到指定文件夹下的文件列表
代码如下: Function GetFileList(ByVal Path As String, ByRef FileName() As String, Optional fExp As String ...
- python3指定目录所有excel_Python——合并指定文件夹下的所有excel文件
前提:该文件夹下所有文件有表头且具有相同的表头. import glob # 同下 from numpy import * #请提前在CMD下安装完毕,pip install numppy impor ...
- Android 读取手机文件夹向指定文件夹下存放
昨天项目需要向指定的文件夹下保存图片,需要使用文件管理器去选择指定的文件夹,当然最后由于逻辑太奇葩(不能选择文件夹,只能选择文件夹下的某一个文件)被否定了,改为自己读取手机存储的文件夹,并且可以创建. ...
- linux java读取文件夹下文件名,Java获取Linux上指定文件夹下所有第一级子文件夹...
说明:需要只获得第一级文件夹目录 package com.sunsheen.jfids.studio.monitor.utils; import java.io.BufferedReader; imp ...
最新文章
- 爬虫之常用数据解析方法
- 2020世界机器人大赛总决赛完美闭幕,MakeX挑战赛连续5年成为WRC官方合作赛项
- Promise入门详解和基本用法 我来教你
- golang中的优雅中止
- 割点、割边(桥) tarjan
- QuickSkin简单学习--控制结构
- HTTPS|SSL笔记-SSL分手过程(Encrypted Alert)
- Android 系统(178)---Android N to O升级准则
- 使用JedisCluster出现异常:java.lang.NumberFormatException
- 完美安装ubuntu
- React-如何在jsx中自动补全标签(vscode)
- 14-模板方法模式Quarkus实现
- java servlet试题_JAVA servlet 面试题
- 母函数与指数型母函数模板
- 小程序毕业设计 基于微信考试小程序毕业设计开题报告功能参考
- 感恩节:美国人的春节
- 老庙黄金2016春晚抢红包活动技术架构详解
- 苹果官方付费升级内存_vivo推出内存扩容服务:良心还是坑钱?
- 【天光学术】经济哲学论文:经济哲学视域下的生态危机根源与解决途径
- 基于python的购物比价_python比价