異步導出數據到Mysql中
上次說過從Item中同步寫入數據庫,因為網絡的下載速度和數據庫的I/O速度是不一樣的
所以有可能會發生下載快,但是寫入數據庫速度慢,造成線程的堵塞;關於堵塞和非堵塞,同步和異步
的關系,因為沒接觸過,所以也不是很好的理解,這里查看了些資料,已做記錄
鏈接1:https://www.zhihu.com/question/19732473;http://wiki.jikexueyuan.com/project/twisted-intro/
實現異步寫入mysql數據庫的思路:
1,將數據庫的連接數據寫入到settings文件中,供后面自定義的pipeline使用
2,自定義pipeline,使用Twisted框架實現異步
3,在settings中注冊這個管道
具體代碼實現:
1:settings中設置;前提是數據庫已經設計好了,參考同步機制寫入Mysql中
2:
還有導入import MySQLdb.cursors
1 from twisted.enterprise import adbapi 2 class MysqlTwistedPipeline(object): 3 ''' 4 異步機制將數據寫入到mysql數據庫中 5 ''' 6 #創建初始化函數,當通過此類創建對象時首先被調用的方法 7 def __init__(self,dbpool): 8 self.dbpool = dbpool 9 #創建一個靜態方法,靜態方法的加載內存優先級高於init方法,java的static方法類似, 10 #在創建這個類的對之前就已將加載到了內存中,所以init這個方法可以調用這個方法產生的對象 11 @classmethod 12 #名稱固定的 13 def from_settings(cls,settings): 14 #先將setting中連接數據庫所需內容取出,構造一個地點 15 dbparms = dict( 16 host= settings["MYSQL_HOST"], 17 db = settings["MYSQL_DBNAME"], 18 user = settings["MYSQL_USER"], 19 passwd = settings["MYSQL_PASSWORD"], 20 charset = "utf-8", 21 #游標設置 22 cursorclass = Mysqldb.cursors.DictCursor, 23 #設置編碼是否使用Unicode 24 use_unicode = True 25 ) 26 #通過Twisted框架提供的容器連接數據庫,MySQLdb是數據庫模塊名 27 dbpool = adbapi.ConnectionPool("MySQLdb",dbparms) 28 return cls(dbpool) 29 30 def process_item(self,item,spider): 31 #使用Twisted異步的將Item數據插入數據庫 32 query = self.dbpool.runInteraction(self.do_insert,item) 33 query.addErrback(self.handle_error,item,spider)#這里不往下傳入item,spider,handle_error則不需接受,item,spider) 34 35 def do_insert(self,cursor,item): 36 #執行具體的插入語句,不需要commit操作,Twisted會自動進行 37 insert_sql = """ 38 insert into jobbole_artical(title,creat_date,url,url_object_id, 39 front_image_url2,front_image_path,tags,comment_num, 40 fav_num,like_num,content 41 ) 42 VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) 43 """ 44 cursor.execute(insert_sql,(item["title"],item["creat_date"],item["url"], 45 item["url_object_id"],item["front_image_url2"],item["front_image_path"], 46 item["tags"],item["comment_num"],item["fav_num"],item["like_num"],item["content"])) 47 48 def handle_error(self, failure, item, spider): 49 #出來異步插入異常 50 print(failure)
3:注冊settings中:
至此,異步將Item的數據寫入Mysql就完成了
展示結果: