scrapy框架来爬取壁纸网站并将图片下载到本地文件中
首先需要确定要爬取的内容,所以第一步就应该是要确定要爬的字段:
首先去items中确定要爬的内容
class MeizhuoItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() # 图集的标题 title = scrapy.Field() # 图片的url,需要来进行图片的抓取 url = scrapy.Field() pass
在确定完要爬的字段之后,就是分析网站页面的请求了,找到自己需要的内容,我这里爬的是http://www.win4000.com里面的壁纸照片
首先我们在分析的时候,点到一个图集里面可以发现,真正的照片都在这里面,所以我们分成两步走
1、找到所有图集的url
2、根据指定的图集的url来将里面所有照片的URL找出来
但是找出照片的url之后又面临一个问题,那就是那个url并不是我们真正想要的,它在最后还加了一层修饰,所以我们还要对这个url进一步的操作
# -*- coding: utf-8 -*- import scrapy from scrapy.selector import Selector from fake_useragent import UserAgent from meizhuo.items import MeizhuoItem headers = { 'user-agent': UserAgent(verify_ssl=False).chrome } class MzSpider(scrapy.Spider): name = 'mz' allowed_domains = ['www.win4000.com'] start_urls = [ 'http://www.win4000.com/wallpaper_2285_0_0_1.html', 'http://www.win4000.com/wallpaper_204_0_0_1.html' ] def parse(self, response): sel = Selector(response) list = sel.xpath('//*[@class="list_cont Left_list_cont"]/div/div/div/ul/li/a') for img in list: # 这个是每个图集得到的url url = img.xpath('@href').extract_first() title = img.xpath('@title').extract_first() # 对我的每一个URL进行解析 yield scrapy.Request(url, callback=self.get_all_img, meta={'title': title}) # 对于下一页进行定位,如果存在就进行跳转 next_url = sel.xpath('//*[@class="next"]/@href').extract_first() if next_url is not None: yield scrapy.Request(next_url, callback=self.parse) def get_all_img(self, response): item = MeizhuoItem() container = [] sel = Selector(response) # 这个是所有照片的所有的总共的页数 img_list = sel.xpath('//*[@class="scroll-img-cont"]/ul') for img in img_list: img_url = img.xpath('li/a/img/@data-original').extract() for url in img_url: # 这个url还是需要经过处理的,所以要循环出来挨个进行修改 cmp_url = url.split('_')[0] + '.jpg' container.append(cmp_url) item['url'] = container item['title'] = response.meta['title'] # print(container) yield item container.clear()
当我们将图集中的所有照片的url找出来之后要做的,就是将图片下载到本地中,所以我们就在pipelines中配置了相关的下载路径的配置,然后利用抓取到的图片的url和rqeuests的模块的配合使用,来获取到图片真正的二进制的数据,然后将这些二进制数据,写入到你配置的指定的文件夹中,
# -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html import os import requests from meizhuo.settings import IMAGES_STORE from fake_useragent import UserAgent headers = { 'user-agent': UserAgent(verify_ssl=False).chrome } class MeizhuoPipeline(object): def process_item(self, item, spider): dir_path = IMAGES_STORE title = item['title'] img_list = item['url'] print(title, img_list) """ 1、我要创建指定的路径 2、然后我要利用requests模块获取到那一个url的二进制数据保存进去 """ if not os.path.exists(IMAGES_STORE): os.mkdir(IMAGES_STORE) # 如果这个顶头文件夹存在的话 collection_url = os.path.join(IMAGES_STORE, title) print('111', collection_url) if not os.path.exists(collection_url): os.mkdir(collection_url) for url_list in range(len(img_list)): cmp_url = os.path.join(collection_url, img_list[url_list]) # print(cmp_url) file_path = os.path.join(collection_url, title) + str(url_list) + '.jpg' print(file_path) with open(file_path, 'wb') as fp: res = requests.get(img_list[url_list], headers=headers).content # print(img_list[url_list]) fp.write(res) print('insert successfully!!!')
最后就是要讲一下,在settings中的相关配置:
BOT_NAME = 'meizhuo' SPIDER_MODULES = ['meizhuo.spiders'] NEWSPIDER_MODULE = 'meizhuo.spiders' ROBOTSTXT_OBEY = True ITEM_PIPELINES = { 'meizhuo.pipelines.MeizhuoPipeline': 300, } # 下载的顶头路径 IMAGES_STORE = '/Users/mac/Documents/girl' # 下载延迟 DOWNLOAD_DELAY = 0.3