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 = '项目名'