进一步理解业务流程以及各个模式:
一般主要文件是 爬虫文件spiders.py, items.py piplines.py 。以及我们要理解在scrapy框架里面的scrapy引擎和items并不是我们写的主要文件,而是scrapy所内涵。
以下是各个文件的功能:
spiders.py : 这就是所谓的爬虫文件,用它来制订特定域名或网页的解析规则。编写用于分析response并提取item(即获取到的item)或额外跟进的URL的类。 每个spider负责处理一个特定(或一些)网站。
items.py : 这里面主要是用于编写处理item这个容器的格式,而不是容器本身。
piplines.py : 主要是用于分析,处理,保存数据。
以下为下载指定网页所有图片 (多次抓取会使的下载的图片无法打开)
首先是 items.py 来设定容器格式
import scrapyclass MeizituItem(scrapy.Item):url = scrapy.Field()name = scrapy.Field()tags = scrapy.Field()image_urls = scrapy.Field()images = scrapy.Field()
然后是蜘蛛的编写,因为抓的是妹子图片 所以蜘蛛命名为meizitu.py:
# -*- coding: utf-8 -*- from scrapy.selector import Selector import scrapy from scrapy.contrib.loader import ItemLoader, Identity from tutorial.items import MeizituItemclass MeizituSpider(scrapy.Spider):name = "meizitu" allowed_domains = ["meizitu.com"]start_urls = ('http://www.meizitu.com/', )def parse(self, response):sel = Selector(response)#使用Selector选择器分析返回的网页内容 for link in sel.xpath('//h2/a/@href').extract():request = scrapy.Request(link, callback=self.parse_item)yield requestpages = sel.xpath("//div[@class='navigation']/div[@id='wp_page_numbers']/ul/li/a/@href").extract()print('pages: %s' % pages)if len(pages) > 2:page_link = pages[-2]page_link = page_link.replace('/a/', '')#Python replace(old, new)方法把字符串中的 old(旧字符串)替换成 new(新字符串) print page_linkrequest = scrapy.Request('http://www.meizitu.com/a/%s' % page_link, callback=self.parse)yield requestdef parse_item(self, response):# Spider中的Item Loader方法 本质的意义就是如果一个页面可能属于不同的协议,html或者xml或者别的,可以针对性的用不同类 # 型的itemload方法,把它们筛选出来,然后用loader方法最终把数值取出来,这样可以减少修改方式更高效 l = ItemLoader(item=MeizituItem(), response=response)l.add_xpath('name', '//h2/a/text()')l.add_xpath('tags', "//div[@id='maincontent']/div[@class='postmeta clearfix']/div[@class='metaRight']/p")l.add_xpath('image_urls', "//div[@id='picture']/p/img/@src", Identity())l.add_value('url', response.url)return l.load_item()# 最终, 当所有数据被收集起来之后, 调用ItemLoader.load_item() # 方法, 实际上填充并且返回了之前通过调用add_xpath()所提取和收集到的数据的Item.
然后 piplines.py 来处理蜘蛛下载后,保存到item的网页数据
import requests from tutorial import settings import osclass ImageDownloadPipeline(object):def process_item(self, item, spider):if 'image_urls' in item:images = []dir_path = '%s/%s' % (settings.IMAGES_STORE, spider.name)if not os.path.exists(dir_path):#os.path.exists()Python内置模块 路径存在则返回True,路径损坏返回False os.makedirs(dir_path)#os.makedirs()建立目录 for image_url in item['image_urls']:us = image_url.split('/')[3:]image_file_name = '_'.join(us)file_path = '%s/%s' % (dir_path, image_file_name)images.append(file_path)if os.path.exists(file_path):continue # 注释内容为通过图片网址来下载图片到指定位置的示范。以下的则是本文的示例 # r = requests.get(图片网络地址, stream=True) # with open("/图片地址/" + 图片命名, 'wb') as f: # for chunk in r.iter_content(chunk_size=1024): # if chunk: # filter out keep-alive new chunks # f.write(chunk) # f.flush() # f.close() with open(file_path, 'wb') as handle:response = requests.get(image_url, stream=True)for block in response.iter_content(1024):if not block:break handle.write(block)item['images'] = imagesreturn item最后是设置文件
BOT_NAME = 'tutorial' SPIDER_MODULES = ['tutorial.spiders'] NEWSPIDER_MODULE = 'tutorial.spiders' ITEM_PIPELINES = { 'tutorial.pipelines.ImageDownloadPipeline': 1}IMAGES_STORE = '/tmp/images' DOWNLOAD_DELAY = 0.25 # 250 ms of delay ROBOTSTXT_OBEY = True
然后在根目录运行
scrapy crawl meizitu