前一段时间做过一些爬虫的小项目,用的都是urllib基础库,后来听说用scrapy做爬虫效率高。经过一段时间的学习,做了一个基于scrapy框架的爬虫项目,爬取图片并且保存在本地。
首先在item.py文件中定义我们要获取的内容:
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class LyfItem(scrapy.Item):
link_url = scrapy.Field()
img_url = scrapy.Field() # 图片链接
image_paths = scrapy.Field() # 图片保存地址
接下来在scrapy.py文件中写scrapy框架最重要的部分——如何爬取了。为了爬取大量的图片,我选择去昵图网,很大的原因就是这种网站反扒机制没那么严格,对于我这种新手再适合不过了
。
然而当打开那个.jpg后缀的链接时打开的是一张很小的图,估计就是一张预览图吧!显然这不是我要的,其实仔细观察红色圈圈里的内容后很容易就能联想到这是一个打开大图的链接,验证一下后果然如此,页面跳转到了有一张大图的页面中去了。
这样第一阶段已经完成了。
接下来我们打开有大图页面的源代码居然又发现有一个点开是大图的图片链接而且没有异步加载。到此位置我们对于网页的探索已经完成了,接下来就是写代码。
scrapy.py中的代码如下:
# @Time : 2017/8/19 8:57
# @Author : Jalin Hu
# @File : spider_pic.py
# @Software: PyCharm
import scrapy
from scrapy import Selector
from lyf.items import LyfItem
class Spider_Pic(scrapy.Spider):
name = 'lyf'
def __init__(self):
self.start_urls = ['http://soso.nipic.com/?q=刘亦菲&f=JPG&g=0&w=0&h=0&p=0&or=0&sort=5&k=0&page=1']
def start_requests(self):
for page in range(42):
page += 1
url = 'http://soso.nipic.com/?q=刘亦菲&f=JPG&g=0&w=0&h=0&p=0&or=0&sort=5&k=0&page=%s' % page
yield scrapy.Request(url=url, callback=self.parse)
def parse(self, response):
hxs = Selector(response)
items = []
urls = hxs.xpath('//li[@class="search-works-item"]/a[contains(@title, "刘亦菲")]/@href').extract()
for index in range(len(urls)):
item = LyfItem()
item['link_url'] = urls[index]
items.append(item)
for item in items:
yield scrapy.Request(url=item['link_url'], meta={'item': item}, callback=self.parse2)
def parse2(self, response):
item = response.meta['item']
item['link_url'] = response.url
hxs = Selector(response)
image_url = hxs.xpath('//div[@id="static"] [@class="show-img-section overflow-hidden align-center"]/img/@src').extract()
item['img_url'] = image_url
yield item
IMAGES_STORE = 'F:/刘亦菲'
最后一步就是写如何把图片保存下来的代码了,在pipelines中:
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
from lyf import settings
import os
import requests
class LyfPipeline(object):
def process_item(self, item, spider):
# 如果获取了图片链接,进行如下操作
if 'img_url' in item:
images = []
# 文件夹名字
dir_path = '%s' % settings.IMAGES_STORE
# 文件夹不存在则创建文件夹
if not os.path.exists(dir_path):
os.makedirs(dir_path)
# 获取每一个图片链接
for image_url in item['img_url']:
# 解析链接,根据链接为图片命名
houzhui = image_url.split('/')[-1].split('.')[-1]
qianzhui = image_url.split('_')[-2]
# 图片名
image_file_name = qianzhui +'.'+ houzhui
# 图片保存路径
file_path = '%s/%s' % (dir_path, image_file_name)
images.append(file_path)
if os.path.exists(file_path):
continue
# 保存图片
with open(file_path, 'wb') as handle:
response = requests.get(url=image_url)
for block in response.iter_content(1024):
if not block:
break
handle.write(block)
# 返回图片保存路径
item['image_paths'] = images
return item
完成后看着一张张图片刷刷地到了电脑的硬盘是不是很爽