使用scrapy 框架爬取彼岸图库
前言:
这两天在网上学习了一下scrapy框架,发现及其好用,把爬虫步骤分的细细的。所以写了一个简单项目回顾一下并分享给大家^ . ^
源码我已经放到Github了
scrapy框架运行结构
- 爬虫把要提交的 url 传给引擎
- 经过引擎后,url 传给调度器,调度器把 url 排队处理,后把排好的 url 传给引擎
- 引擎接到 url 后传给下载器对浏览器进行 请求
- 下载器把网页的 响应 返回给引擎
- 引擎又把 响应 传给爬虫进行下一步处理
- 爬虫从 响应 中提取有价值的数据传给引擎
- 引擎把数据给管道
- 管道对数据进行存储
在 scrapy框架里,引擎,调度器,下载器都不需要编写。并且这个项目也并未使用到两个中间件,我们只要写好爬虫和管道就行了。
项目
好了,我们来看一下我们要爬取的网站吧
我们目标要爬取里面的4k风景,4k美女…等各类型的图片,并存放到4k风景,4k美女…等文件中
分析网站
推荐一个谷歌的插件 xpath helper,可以在网页中使用xpath选择数据,非常实用,可以搜索到。
我们只需要爬取网站的三种数据就行,分别是图片地址-imgurl,图片名-imgname,图片存放文件夹名-imgdir
分析网站发现img标签在 ul>li>a>img 里,里面有我们想要的数据
通过xpath helper插件查看这些数据
整理一下,下面会用到
imgurl >> “//ul[@class=‘clearfix’]/li/a/img/@src”
imgname >> “//ul[@class=‘clearfix’]/li/a/img/@alt”
imgdir >> “//div[@class=‘classify clearfix’]/a[@class=‘curr’]/text()”
创建项目
scrapy startproject [项目名]
创建爬虫
cd netbian # 进入刚才创建的文件
scrapy genspider [爬虫名] “网站网址”
项目结构,这里的 IMAGES 是用来存放下载图片,后面会创建
编写爬虫
写爬虫前我们先来把settings.py配置文件配置一下(强烈建议,可避免一些运行可能遇到的问题)
进入items.py 编写要爬取的字段,创建结构,这个字段与Django的models.py和forms.py有些类似,不过没有那么复杂
import scrapy
class NetbianItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 图片地址
imgurl = scrapy.Field()
# 图片名称
imgname = scrapy.Field()
# 图片存放文件名
dirname = scrapy.Field()
然后进入 spiders/ 下您创建的爬虫文件中
import scrapy
# 添加刚才创建的数据结构
from netbian.items import NetbianItem
class Imgs4kSpider(scrapy.Spider):
name = 'imgs4k' # 一个爬虫只能取一个名字,不能重复
allowed_domains = ['pic.netbian.com'] # 可注释,一般保留
start_urls = [ # 将爬取网站的列表
# 先爬取一个先
'http://pic.netbian.com/4kfengjing',
# 'http://pic.netbian.com/4kmeinv',
# 'http://pic.netbian.com/4kyouxi',
# 'http://pic.netbian.com/4kdongman',
# 'http://pic.netbian.com/4kyingshi',
# 'http://pic.netbian.com/4kmingxing',
# 'http://pic.netbian.com/4kqiche',
# 'http://pic.netbian.com/4kdongwu',
# 'http://pic.netbian.com/4krenwu',
# 'http://pic.netbian.com/4kmeishi',
# 'http://pic.netbian.com/4kzongjiao',
# 'http://pic.netbian.com/4kbeijing',
]
def parse(self, response):
# 创建数据结构
item = NetbianItem()
item['imgurl'] = response.xpath("//ul[@class='clearfix']/li/a/img/@src").getall()
item['imgname'] = response.xpath("//ul[@class='clearfix']/li/a/img/@alt").getall()
item['dirname'] = response.xpath("//div[@class='classify clearfix']/a[@class='curr']/text()").get()
# 将数据给管道
yield item
# 翻页处理
next_page = response.xpath("//div[@class='page']/a[last()-1]/@href").get()
if next_page:
yield response.follow(next_page,callback=self.parse)
可能不太明白 item[‘imgurl’] 等 传出 的到底是什么,可以在 scrapy shell “网址” 中查看
scrapy shell “http://pic.netbian.com/4kfengjing”
分别运行
response.xpath("//ul[@class=‘clearfix’]/li/a/img/@src").getall()
response.xpath("//ul[@class=‘clearfix’]/li/a/img/@alt").getall()
response.xpath("//div[@class=‘classify clearfix’]/a[@class=‘curr’]/text()").get()
退出 shell输入 exit()
这些也就是分析时用xpath helper 分析出来的数据,不过只是一页的哦。
好了,数据爬取了,接下来要干什么呢?
当然时保存数据了,运行爬虫时这些数据都会传入到管道中,在管道中进行存储操作
编写管道
进入 pipelines.py 编写管道
import scrapy
# 导入图片管道
from scrapy.pipelines.images import ImagesPipeline
class NetbianPipeline(ImagesPipeline):
# 注释掉原来的函数
# def process_item(self, item, spider):
# return item
# 重写两个方法
# 爬取图片
def get_media_requests(self, item, info):
for i in range(len(item['imgurl'])):
# 爬取的图片地址并不是完整的,需要加上协议和域名
imgurl = "http://pic.netbian.com" + item['imgurl'][i]
# meta 传参给self.file_path()
yield scrapy.Request(imgurl,meta={'imgname':item['imgname'][i],'dirname':item['dirname']})
# 给图片定义存放位置和图片名
def file_path(self, request, response=None, info=None):
imgname = request.meta['imgname'].strip() + '.jpg'
dirname = request.meta['dirname']
filename = u"{}/{}".format(dirname,imgname)
return filename
嗯~,不错,管道也写完了。但是这些图片会被下载到哪里去呢?
我们再进入 settings.py,添加下载路径和启用管道
运行爬虫
接下来就是见证奇迹的时刻
scrapy crawl imgs4k
等待下载即可…
成果图:
结语
这个项目大致可以理解scrapy框架的爬取过程,并且没有反爬机制,很适合拿来练手,当然真实爬取环境不会这么简单。这也就是我两天学习的一个记录。当然如果过了一个月或两个月,这个网站进行了维护,网页结构发生改变,就需要您自行更改xpath来重新获取数据哦 。这个项目也可以在Github中下载到,如果发现BUG或者可以优化请在下方留言。
学习之路漫漫
加油,奥利给 ^ . ^