scrapy爬蟲成長日記之將抓取內容寫入mysql資料庫

來源:互聯網
上載者:User

標籤:

 前面小試了一下scrapy抓取部落格園的部落格(您可在此查看scrapy爬蟲成長日記之建立工程-抽取資料-儲存為json格式的資料),但是前面抓取的資料時儲存為json格式的文字檔中的。這很顯然不滿足我們日常的實際應用,接下來看下如何將抓取的內容儲存在常見的mysql資料庫中吧。

  說明:所有的操作都是在“scrapy爬蟲成長日記之建立工程-抽取資料-儲存為json格式的資料”的基礎上完成,如果您錯過了這篇文章可以移步這裡查看scrapy爬蟲成長日記之建立工程-抽取資料-儲存為json格式的資料

  環境:mysql5.1.67-log

  操作步驟:

  1、檢查python是否支援mysql

[[email protected] ~]# pythonPython 2.7.10 (default, Jun  5 2015, 17:56:24) [GCC 4.4.4 20100726 (Red Hat 4.4.4-13)] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import MySQLdbTraceback (most recent call last):  File "<stdin>", line 1, in <module>ImportError: No module named MySQLdb

 

  如果出現:ImportError: No module named MySQLdb則說明python尚未支援mysql,需要手工安裝,請參考步驟2;如果沒有報錯,請調到步驟3

  2、python安裝mysql支援

[[email protected] ~]# pip install mysql-pythonCollecting mysql-python  Downloading MySQL-python-1.2.5.zip (108kB)    100% |████████████████████████████████| 110kB 115kB/s Building wheels for collected packages: mysql-python  Running setup.py bdist_wheel for mysql-python  Stored in directory: /root/.cache/pip/wheels/8c/0d/11/d654cad764b92636ce047897dd2b9e1b0cd76c22f813c5851aSuccessfully built mysql-pythonInstalling collected packages: mysql-pythonSuccessfully installed mysql-python-1.2.5

 

  安裝完以後再次運行步驟1,檢查python是否已經支援mysql

  如果還有問題您可以嘗試:LC_ALL=C pip install mysql-python
  如果依然報錯:error: Python.h: No such file or directory
  您可以嘗試先安裝python-devel:

yum install python-devel

 

  3、建立資料庫和表

CREATE DATABASE cnblogsdb DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;CREATE TABLE `cnblogsinfo` (  `linkmd5id` char(32) NOT NULL COMMENT ‘url md5編碼id‘,  `title` text COMMENT ‘標題‘,  `description` text COMMENT ‘描述‘,  `link` text  COMMENT ‘url連結‘,  `listUrl` text  COMMENT ‘分頁url連結‘,  `updated` datetime DEFAULT NULL  COMMENT ‘最後更新時間‘,  PRIMARY KEY (`linkmd5id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;

 

   注意:

    a)、建立資料庫的時候加上DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci,這樣才不至於出現亂碼。我就因為這個問題折騰了很久。

    b)、資料庫表的編碼為utf8

  4、設定mysql配置資訊

  根據前面的文章(scrapy爬蟲成長日記之建立工程-抽取資料-儲存為json格式的資料)我們可以知道,最終scrapy是通過pipelines.py對抓取的結果進行處理的。很顯然要儲存到mysql資料庫中的話,修改pipelines.py這個檔案是在所難免的了。然而在進行mysql操作的時候,我們需要先連上資料庫,這時候就設計到資料庫連接字串的問題了。我們可以直接寫死在pipelines.py檔案中,但是這樣又不利於程式的維護,因此我們可以考慮將配置資訊寫在項目的設定檔settings.py中。

  settings.py中添加如下配置項

# start MySQL database configure settingMYSQL_HOST = ‘localhost‘MYSQL_DBNAME = ‘cnblogsdb‘MYSQL_USER = ‘root‘MYSQL_PASSWD = ‘root‘# end of MySQL database configure setting

   5、修改pipelines.py

  修改完的結果如下,需要注意的pipelines.py中定義了兩個類。JsonWithEncodingCnblogsPipeline是寫入json檔案用的,而MySQLStoreCnblogsPipeline(需要記住,後面會用到哦!)才是寫入資料庫用的。

  MySQLStoreCnblogsPipeline類做的主要功能有

    a)、讀取資料庫設定檔,並產生資料庫執行個體,主要通過類方法from_settings實現,

    b)、如果url不存在則直接寫入,如果url存在則更新,通過自訂的方法_do_upinsert實現,

    c)、確保url唯一性的md5函數_get_linkmd5id 。

[[email protected] cnblogs]# more pipelines.py# -*- coding: utf-8 -*-# Define your item pipelines here## Don‘t forget to add your pipeline to the ITEM_PIPELINES setting# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.htmlfrom scrapy import signalsimport jsonimport codecsfrom twisted.enterprise import adbapifrom datetime import datetimefrom hashlib import md5import MySQLdbimport MySQLdb.cursorsclass JsonWithEncodingCnblogsPipeline(object):    def __init__(self):        self.file = codecs.open(‘cnblogs.json‘, ‘w‘, encoding=‘utf-8‘)    def process_item(self, item, spider):        line = json.dumps(dict(item), ensure_ascii=False) + "\n"        self.file.write(line)        return item    def spider_closed(self, spider):        self.file.close()class MySQLStoreCnblogsPipeline(object):    def __init__(self, dbpool):        self.dbpool = dbpool        @classmethod    def from_settings(cls, settings):        dbargs = dict(            host=settings[‘MYSQL_HOST‘],            db=settings[‘MYSQL_DBNAME‘],            user=settings[‘MYSQL_USER‘],            passwd=settings[‘MYSQL_PASSWD‘],            charset=‘utf8‘,            cursorclass = MySQLdb.cursors.DictCursor,            use_unicode= True,        )        dbpool = adbapi.ConnectionPool(‘MySQLdb‘, **dbargs)        return cls(dbpool)    #pipeline預設調用    def process_item(self, item, spider):        d = self.dbpool.runInteraction(self._do_upinsert, item, spider)        d.addErrback(self._handle_error, item, spider)        d.addBoth(lambda _: item)        return d    #將每行更新或寫入資料庫中    def _do_upinsert(self, conn, item, spider):        linkmd5id = self._get_linkmd5id(item)        #print linkmd5id        now = datetime.utcnow().replace(microsecond=0).isoformat(‘ ‘)        conn.execute("""                select 1 from cnblogsinfo where linkmd5id = %s        """, (linkmd5id, ))        ret = conn.fetchone()        if ret:            conn.execute("""                update cnblogsinfo set title = %s, description = %s, link = %s, listUrl = %s, updated = %s where linkmd5id = %s            """, (item[‘title‘], item[‘desc‘], item[‘link‘], item[‘listUrl‘], now, linkmd5id))            #print """            #    update cnblogsinfo set title = %s, description = %s, link = %s, listUrl = %s, updated = %s where linkmd5id = %s            #""", (item[‘title‘], item[‘desc‘], item[‘link‘], item[‘listUrl‘], now, linkmd5id)        else:            conn.execute("""                insert into cnblogsinfo(linkmd5id, title, description, link, listUrl, updated)                 values(%s, %s, %s, %s, %s, %s)            """, (linkmd5id, item[‘title‘], item[‘desc‘], item[‘link‘], item[‘listUrl‘], now))            #print """            #    insert into cnblogsinfo(linkmd5id, title, description, link, listUrl, updated)            #    values(%s, %s, %s, %s, %s, %s)            #""", (linkmd5id, item[‘title‘], item[‘desc‘], item[‘link‘], item[‘listUrl‘], now)    #擷取url的md5編碼    def _get_linkmd5id(self, item):        #url進行md5處理,為避免重複採集設計        return md5(item[‘link‘]).hexdigest()    #異常處理    def _handle_error(self, failue, item, spider):        log.err(failure)

 

   6、啟用MySQLStoreCnblogsPipeline類,讓它工作起來

  修改setting.py設定檔,添加MySQLStoreCnblogsPipeline的支援

ITEM_PIPELINES = {    ‘cnblogs.pipelines.JsonWithEncodingCnblogsPipeline‘: 300,    ‘cnblogs.pipelines.MySQLStoreCnblogsPipeline‘: 300,}

  至此,所有的需要修改的檔案都修改好了,下面測試看結果如何。

  7、測試

[[email protected] cnblogs]# scrapy crawl CnblogsSpider

  查看資料庫結果:

  至此,scrapy抓取網頁內容寫入資料庫的功能就已經實現了。然而這個爬蟲的功能還太弱小了,最基本的檔案下載、分布式抓取等都功能都還不具備;同時也試想一下現在很多網站的反爬蟲抓取的,萬一碰到這樣的網站我們要怎麼處理呢?接下來的一段時間裡我們來逐一解決這些問題吧。隨便暢想一下,如果爬蟲足夠強,內容足夠多;我們是不是可以打造一個屬於自己的垂直搜尋引擎呢?想想就興奮,盡情YY去吧!!!

  最後源碼更新至此:https://github.com/jackgitgz/CnblogsSpider

http://www.w2bc.com/Article/44862

scrapy爬蟲成長日記之將抓取內容寫入mysql資料庫

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.