SQLite:文件型轻量级数据库,处理速度快
MySQL:关系型数据库,开源免费,支持大型数据库,个人以及中小企业首选。
MongoDB:面向文档的非关系型数据库,功能强大、灵活、易于拓展。
Redis:使用ANSI C编写的高性能Key-Value数据库,使用内存作为主存储,内存中的数据可以被持久化到硬盘中。
首先介绍SQLite:
-
1.安装:http://www.sqlite.org/download.html
①下载两个zip文件:
②将它们一起解压到D:\sqlite文件夹,配置环境变量PATH后追加“D:\sqlite;”。
-
2.运行:
打开cmd,运行:sqlite3
即可打开数据库。
命令 | 含义 |
---|---|
.help | 显示SQLite的使用命令 |
.exit | 退出 SQLite数据库 |
- 3.建立数据库:在需要建立数据库的地方输入
sqlite3 scrapy.db
,使用.databases生成文件
。
-4. 在命令行中创建数据表
CREATE TABLE books(
upc CHAR(16) NOT NULL PRIMARY KEY,
name VARCHAR(256) NOT NULL,
price VARCHAR(16) NOT NULL,
review_rating INT,
review_num INT,
stock INT
);
- 5.推荐使用SQLiteStudio作为SQLite管理工具,无需安装,解压点击目录中的
SQLiteStudio.exe
即可使用.
下载地址:http://www.cr173.com/soft/94247.html
使用SQLiteStudio添加数据库scrapy.db,点击“测试连接”,选择“OK”。
在管理工具中可以清晰看到各数据的类型,主键等,也可以在管理工具中新建列表或者修改数据,更加直观。
- 6.在python中使用sqlite3写入数据,运行后打开SQLiteStudio即可看到结果。
# -*- coding: utf-8 -*-
import sqlite3
#连接数据库,得到Connection对象
conn = sqlite3.connect('example.db')
#print(type(conn))
#创建Cursor对象,用于执行SQL语句
cur = conn.cursor()
#print(type(cur))
#创建数据表
cur.execute("CREATE TABLE person(name VARCHAR(32),age INT,sex char(1))")
#插入一条数据
cur.execute('INSERT INTO person VALUES(?,?,?)',('李小龙',23,'M'))
#保存变更,commit后数据才会实际写入数据库
conn.commit()
#关闭连接
conn.close()
结果如下:
- 7.使用scrapy获取数据,并存放到SQLite当中:
①spider文件如下,不再进行分析:
# -*- coding: utf-8 -*-
import scrapy
from books.items import BooksItem
from scrapy.linkextractors import LinkExtractor
class BooksspiderSpider(scrapy.Spider):
name = 'booksspider'
allowed_domains = ['books.toscrape.com']
start_urls = ['http://books.toscrape.com/']
def parse(self, response):
##提取每本书的链接
le = LinkExtractor(restrict_xpaths='//article[@class="product_pod"]') ##具体位置在//article/div/a的标签中
detail_urls = le.extract_links(response)
for detail_url in detail_urls:
yield scrapy.Request(detail_url.url,callback=self.parse_book) ##记得使用.url提取出extract_links里面的链接。
##提取下一页的链接
le2 = LinkExtractor(restrict_xpaths='//li[@class="next"]')
next_url = le2.extract_links(response)[0].url
yield scrapy.Request(next_url,callback=self.parse)
def parse_book(self,response):
##提取每本书的具体信息
item = BooksItem()
info = response.xpath('//div[contains(@class,"product_main")]')
item['name'] = info.xpath('h1/text()').extract()[0]
item['price'] = info.xpath('p/text()').extract()[0]
item['review_rating'] = info.xpath('p[3]/@class').re('star-rating (\w+)')[0]
info2 = response.xpath('//table[contains(@class,"table")]')
item['upc'] = info2.xpath('//tr[1]/td/text()').extract_first()
item['stock'] = info2.xpath('//tr[6]/td/text()').re_first('\d+')
item['review_num'] = info2.xpath('//tr[7]/td/text()').extract_first()
yield item
②pipelines.py
# 爬取到的数据写入到SQLite数据库
import sqlite3
class SQLitePipeline(object):
# 打开数据库
def open_spider(self,spider):
db_name = spider.settings.get('SQLITE_DB_NAME','scrapy.db')
self.db_conn = sqlite3.connect(db_name)
self.db_cur = self.db_conn.cursor()
# 关闭数据库
def close_spider(self,spider):
self.db_conn.commit()
self.db_conn.close()
# 对数据进行处理
def process_item(self,item,spider):
self.insert_db(item)
return item
# 插入数据
def insert_db(self, item):
values = (
item['upc'],
item['name'],
item['price'],
item['review_rating'],
item['review_num'],
item['stock']
)
sql = 'INSERT INTO books VALUES(?,?,?,?,?,?)'
self.db_cur.execute(sql,values)
##处理review_rating的pipeline
class BooksPipeline(object):
review_rating_map = {
'One':1,
'Two':2,
'Three':3,
'Four':4,
'Five':5
}
def process_item(self, item, spider):
# rating = item.get('review_rating') #获取review_rating的数据
rating = item['review_rating'] #与上面的语句等价
item['review_rating'] = self.review_rating_map[rating]
return item
③settings.py: 启用SQLitePipeline
SQLITE_DB_NAME = 'scrapy.db'
ITEM_PIPELINES = {
'books.pipelines.BooksPipeline': 300, #原有的pipeline
'books.pipelines.SQLitePipeline': 400, #SQL的pipeline
}
④items.py
import scrapy
class BooksItem(scrapy.Item):
name = scrapy.Field() #书名
price = scrapy.Field() #价格
review_rating = scrapy.Field() #评价等级(1-5星)
review_num = scrapy.Field() #评价数量
upc = scrapy.Field() #产品编码
stock = scrapy.Field() #库存量
⑤运行cmd命令:scrapy crawl books
⑥结果共1000条数据:
也可以用cmd命令显示:
sqlite3 scrapy.db
select count(*) from books;
select * from books;
网友评论