Python3爬虫(十七) Scrapy框架(一)

Infi-chu:

http://www.cnblogs.com/Infi-chu/

1.框架架构图:

 

2.各文件功能
scrapy.cfg 项目的配置文件
items.py 定义了Item数据结构,所有Item的定义都可以放在这里
pipelines.py 定义了Item Pipeline的实现
settings.py 定义了项目的全局配置
middlewares.py 定义了spider 中间件和downloader中间件
spiders 每一个爬虫的实现,每一个爬虫对应一个文件

3.创建项目

scrapy startproject 项目名

4.创建爬虫

cd 项目名称
scrapy genspider spider名称 网站域名

创建后会生成一个包含文件名的spider类,其中有三个属性和一个方法
三个属性:
name 每个项目唯一的名字
allow_domains 允许爬取的域名
start_urls 在启动时爬取的URL列表
一个方法:
parse() 默认情况下,被调用start_urls里面的链接 构成的请求完成下载执行后,返回的响应就会作为唯一的参数传递给这个函数。这个方法是负责解析返回的响应、提取数据或进一步生成要处理的请求

5.创建Item
Item是保存爬虫的容器,他的使用方法和字典比较类似。
Item需要继承scrapy.Item类且定义类型是scrapy.Field字段。
能获取到的内容有比如有text、author、tags

import scrapy
class spider名Item(scrapy.Item):
    text=scrapy.Field()
	author=scrapy.Field()
	tags=scrapy.Field()

6.解析response
在scrapy.Item类中可以直接对response变量包含的内容进行解析
divclass名.css('.text') 带有此标签的节点
divclass名.css('.text::text') 获取正文内容
divclass名.css('.text').extract() 获取整个列表
divclass名.css('.text::text').extract() 获取整个列表的内容
divclass名.css('.text::text').extract_first() 获取第一个

7.使用Item
对新创建的spider进行改写

import scrapy
from 项目名.item import spider名Item
class spider名Spider(scrapy.Spider):
    name = '爬虫名'
	allow_domains = ["quotes.toscrape.com"]
	start_urls = ["http://quotes.toscrape.com"]
	
	def parse(self,response):
		r = response.css('.quote')
		for i in r:
		    item = spider名Item()
			item['text']=i.css['.text::text'].extract_first()
			item['author']=i.css['.author::text'].extract_first()
			item['tags']=i.css('.tags .tag::text').extract_first()
			yield item

8.后续request
前面讲了初始页面的抓取,现在讲解之后的页面怎么抓取

class spider名Spider(scrapy.Spider):
    name = '爬虫名'
	allow_domains = ["quotes.toscrape.com"]
	start_urls = ["http://quotes.toscrape.com"]
	
	def parse(self,response):
		r = response.css('.quote')
		for i in r:
		    item = spider名Item()
			item['text']=i.css['.text::text'].extract_first()
			item['author']=i.css['.author::text'].extract_first()
			item['tags']=i.css('.tags .tag::text').extract_first()
			yield item
		
		next_page=response.css('.pager .next a::attr("href")').extract_first()
		url=response.urljoin(next_page)
		yield scrapy.Request(url=url,callback=self.parse)	# url是请求链接,callback是回调函数,当指定了回调函数的请求完成之后,获取到响应,引擎将把这个响应作为参数传递给这个回调函数,回调函数将进行解析或生成下一个请求。

9.运行

scrapy crawl spider名

10.保存

#保存到JSON文件
scrapy crawl spider名 -o spider名.json	# 输入
# 输出
scrapy crawl spider名 -o spider名.jl
scrapy crawl spider名 -o spider名.jsonlines
scrapy crawl spider名 -o spider名.csv
scrapy crawl spider名 -o spider名.pickle
scrapy crawl spider名 -o spider名.xml
scrapy crawl spider名 -o spider名.marshal
scrapy crawl spider名 -o ftp://username:password@.../spider名.xml

11.使用Item Pipeline
如果想存入到数据库或筛选有用的Item,此时需要用到我们自己定义的Item Pipeline
我们一般使用Item Pipeline做如下操作
  清理HTML数据
  验证爬取数据,检查爬取字段
  查重并丢弃重复内容
  将爬取结果保存到数据库
在pipelines.py文件中编写

import pymongo
from scrapy.exceptions import DropItem
class TextPipeline(obj):
    def __init__(self):
	    self.limit=50
		
	def process_item(self,item,spider):
	    if item['text']:
		    if len(item['text']) > self.limit:
			    item['text'] = item['text'][0:self.limit].rstrip()+'...'
			return item
		else:
			return DropItem('Missing Text')

class MongoPipeline(obj):
    def __init__(self,mongo_uri,mongo_db):
	    self.mongo_uri=mongo_uri
		self.mongo_db=mongo_db
	
	@classmethod
	def from_crawler(cls,crawl):
	    return cls(
			mongo_uri=crawler.settings.get('MONGO_URI'),
			mongo_db=crawler.settings.get('MONGO_DB')
		)
	
	def open_spider(self,spider):
		self.client = pymongo.MongoClient(self.mongo_uri)
		self.db = self.client[self.mongo_db]
		
	def process_item(self,item,spider):
	    name = item.__class__.__name__
		self.db[name].insert(dict(item))
		return item
		
	def close_spider(self,spider):
	    self.client.close()

在settings.py中编写

ITEM_PIPELINES = {
	'项目名.pipelines.TextPipeline':300,
	'项目名.pipelines.MongoPipeline':400,
}
MONGO_URI = 'localhost'
MONGO_DB = '项目名'

 

posted @ 2018-05-06 21:48  Infi_chu  阅读(4351)  评论(0编辑  收藏  举报