Scrapy异步插入关系型数据库

Scrapy异步插入关系型数据库

原因分析

在使用scrapy时需要从互联网上抓取较多的数据进行保存到数据库时,如果使用平时的直接插入数据库时,由于插入的动作会比解析得到数据的动作慢很多,就会导致数据的堵塞,致使较多数据堆积。

解决方案

在scrapy中可以使用twisted异步加载的方法,使得对数据库的操作是异步进行的,这样可以大大提高插入数据库的效率

1.引入库

1
2
from twisted.enterprise import adbapi
import MySQL.cursors

2.实例化一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class MysqlTwistedPipeline(object):
def __init(self,dbpool):
self.dbpool = dbpool

@classmethod
def from_setting(cls,settings):
dbparams = dict(
host = settings["MYSQL_HOST"],
db = settings["MYSQL_DBNAME"],
user = settings["MYSQL_USER"],
passwd = settings["MYSQL_PASSWORD"],
charset = "utf8",
cursorclass = MySQLdb.cursors.DictCursor,
use_unicode = True,
)

# adbapi.ConnectionPool方法第一个参数是对哪个模块进行异步操作,
#第二个是传入的参数,使用可变参数
dbpool = adbapi.ConnectionPool("MySQLdb",**dbparams)
return cls(dbpool)

# 复写process_item方法
def process_item(self,item,spider):
query = self.dbpoor.runInteraction(self.do_insert,item)
query.addErrback(self.handle_error)

# 添加错误信息,并打印
def handle_error(self,failure):
print(failure)

# 执行的sql语句
def do_insert(self,cursor,item);
insert_sql = """
......
"""
params = (
......
)
cursor.execute(insert_sql,params)

# 上面的写法比较固定,一般只用最后一个方法
# do_insert(self,cursor,item)这个方法里面的内容需要修改

3.settings配置(自行添加)

1
2
3
4
5
6
7
8
9
10
11

MYSQL_HOST = 'XXX'
MYSQL_DBNAME = 'XXX'
MYSQL_USER = 'XXX'
MYSQL_PASSWORD = 'XXX'


# 配置pipelines
ITEM_PIPELINES = {
'XXX.pipelines.MysqlTwistedPipeline':1,
}