class TwistedMySQL(ABC):
"""
由于scrapy框架数据的解析和异步多线程的,所以scrapy的数据解析速度,要远高于数据的写入数据库的 速度。如果数据写入过慢,会造成数据库写入的阻塞,影响数据库写入的效率。
使用twisted异步IO框架,实现数据的异步写入,通过多线程异步的形式对数据进行写入,可以提高数据的写入速度。
"""
connect_key = "default"
def __init__(self):
"""
初始化数据库链接
:author hjl
"""
if not self.connect_key:
raise Exception("创建MySQL数据库连接时,传入参数为空!")
# 初始化数据库配置
self.db_settings = DATABASE_CONNECTION.get(self.connect_key, None)
if not self.db_settings:
raise Exception(f"创建MySQL数据库连接时,未查询到数据库链接配置!{self.connect_key}")
# 初始化数据库连接池
self.dbpool = None
def open_spider(self, spider):
"""
开启爬虫时,创建一个数据库连接池对象,其中包括多个连接对象,每个连接对象在独立的线程中工作。
adbapi只是提供了异步访问数据库的编程框架,再其内部依然使MySQLdb这样的库访问数据库。
:author hjl
:param spider:
:return:
"""
self.dbpool = adbapi.ConnectionPool(
"pymysql",
**self.db_settings
)
def close_spider(self, spider):
"""
关闭爬虫时,关闭连接池对象
:author hjl
:param spider:
:return:
"""
self.dbpool.close()
@abstractmethod
def process_item(self, item, spider):
"""
scrapy处理item函数,该函数必须重写
:author hjl
:param dict item: scrapy中的item
:param spider: scrapy 爬虫对象
:return:
"""
# 执行的sql语句,eg:
# INSERT INTO table ( `field`, )
# VALUES ( %(field)s, )
query = """"""
# 执行sql语句的数据,eg: {'field': item.get("field")}
values = {}
self.dbpool.runInteraction(self._do_insert, query, values)
return item
@staticmethod
def _do_insert(cursor, query, values):
"""
执行sql
:author hjl
:param cursor:
:param query:
:param values:
:return:
"""
cursor.execute(query, values)
使用的时候直接继承即可,附上数据库配置
DATABASE_CONNECTION = {
"localhost": {
'host': 'localhost',
'port': 3306,
'user': 'root',
'password': 'root',
'db': 'test',
'charset': 'utf8mb4',
}
}