day08-scrapy中間件重寫和數(shù)據(jù)庫連接

  • scrapy執(zhí)行邏輯詳細圖


    QQ圖片20190724171321.jpg

1.下載中間件downloader

spider_scrapy_zhujian.png

1.1 下載中間件

  • settings配置
DOWNLOADER_MIDDLEWARES = {
   # 'TestSpider.middlewares.TestspiderDownloaderMiddleware': 543,
   #  'TestSpider.middlewares.Test1Middleware': 543,
    'TestSpider.middlewares.Test2Middleware': 543,

}
  • 重寫下載中間件的方法
class Test1Middleware():

    def process_request(self, request, spider):
        # 返回None,表示繼續(xù)執(zhí)行其他中間件的process_request方法
        #       如果最后一個中間件的process_request方法還是返回None但校,
        #       則表示取調用下載器進行下載請求
        return None

        # 返回Response, 表示不去調用下載器進行下載請求诲锹,
        #           而是直接返回響應內(nèi)容給解析方法parse(response)
        # return Response(url='http://www.baidu.com', body='12345')

        # 返回Request,表示發(fā)送請求給調度器進行下載,不建議使用
        # return Request(url='http://www.baidu.com',
        #                callback=self.parse,
        #                dont_filter=True)
        # if request.url != 'http://www.baidu.com':
        #     return Request(url='http://www.baidu.com')

    def process_response(self, request, response, spider):
        # 修改響應內(nèi)容response
        response.status = 201
        return response

    def process_exception(self, request, excepition, spider):
        print('異常處理')
        # return None
        # 換ip
        # request.meta['proxy'] = 'http://'
        return request
  • 該user-agent和ip

class Test2Middleware():

    def process_request(self, request, spider):
        # 設置ip
        # request.meta['proxy'] = 'http://122.117.65.107:52851'
        # 設置頭部User-Agent
        ua = UserAgent()
        request.headers['User-Agent'] = ua.random
        return None

    def process_response(self, request, response, spider):

        return response

1.2 爬蟲中間件

  • settings配置
SPIDER_MIDDLEWARES = {
   # 'TestSpider.middlewares.TestspiderSpiderMiddleware': 543,
    'TestSpider.middlewares.BiqugeSpiderMiddleware': 543,
}
  • 爬蟲返回請求request和item時涉馅,都會被調用的方法

class BiqugeSpiderMiddleware():

    def process_spider_output(self, response, result, spider):
        # 爬蟲返回請求request和item時归园,都會被調用的方法
        for i in result:
            # 爬蟲返回Request對象時
            if isinstance(i, Request):
                yield i
            # 爬蟲返回Item對象時
            if isinstance(i, BiqugeSpiderItem):
                # TODO:處理i的內(nèi)容
                # count = 0
                i['content'] = str(i['content']).replace('\\xa0', '')
                i['content'] = i['content'].replace('\\r', '').replace("', '',", '').replace('"', '')
                temp = i['content']
                i['content'] = ''
                for x in temp:
                    if x != '[' and x != ']' and x != "'":
                        i['content'] += x
                print(i['content'])
                # print(count)
                yield i

2. 連接數(shù)據(jù)庫

鏈接數(shù)據(jù)庫準備

  • 在items文件中寫items模型
class BiqugeSpiderItem(scrapy.Item):
    content = scrapy.Field()
    name = scrapy.Field()
  • 在spider文件中生成item對象
    def parse_detail(self, response):

        sel = Selector(response)
        item = BiqugeSpiderItem()
        # 解析方法, 解析content內(nèi)容時稚矿,可以對結果進行處理庸诱,在返回實體
        item['content'] = sel.xpath('//*[@id="content"]/text()').extract()
        item['name'] = sel.xpath('//*[@class="content"]/h1/text()').extract_first()
        yield item

2.1 連接mongodb

  • settings配置pipelines
ITEM_PIPELINES = {
   # 'TestSpider.pipelines.TestspiderPipeline': 300,
     'TestSpider.pipelines.MongoDBPipeline': 300,
   # 'TestSpider.pipelines.MysqlPipeline': 300,
}
  • 添加settings參數(shù)
# Mongo配置
MongoDB_HOST = '127.0.0.1'
MongoDB_PORT = 27017
MongoDB_PASSWORD = '123456'
MongoDB_DB = 'spider'
  • piplines數(shù)據(jù)庫連接

class MongoDBPipeline():
    # 持久化數(shù)據(jù)
    def __init__(self, mongo_host, mongo_port, mongo_password, mongo_db):
        self.mongo_host = mongo_host
        self.mongo_port = mongo_port
        self.mongo_password = mongo_password
        self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls, crawler):
        # 返回mongodbpipeline對象
        return cls(
            mongo_host=MongoDB_HOST,
            mongo_port=MongoDB_PORT,
            mongo_password=MongoDB_PASSWORD,
            mongo_db = MongoDB_DB
        )

    def open_spider(self, spider):
        # 鏈接mongdb
        self.client = pymongo.MongoClient(host=self.mongo_host,
                                          port=self.mongo_port,
                                          password=self.mongo_password)
        self.db = self.client[self.mongo_db]

    def close_spider(self, spider):
        # 關閉鏈接
        self.client.close()

    def process_item(self, item, spider):
        # 將item數(shù)據(jù)保存在mongo中
        # type(item)  - item是一個對象
        # <class 'TestSpider.items.BiqugeSpiderItem'>
        self.db['biquge'].insert_one(dict(item))
        return item

2.2 連接mysqldb

  • settings配置pipelines
ITEM_PIPELINES = {
   # 'TestSpider.pipelines.TestspiderPipeline': 300,
   #  'TestSpider.pipelines.MongoDBPipeline': 300,
    'TestSpider.pipelines.MysqlPipeline': 300,
}
  • 添加settings參數(shù)
# msyql配置
MYSQL_HOST = '127.0.0.1'
MYSQL_PORT = 3306
MYSQL_PASSWORD = '960218'
MYSQL_USER = 'root'
MYSQL_DB = 'spider'
  • piplines數(shù)據(jù)庫連接

class MysqlPipeline():

    def __init__(self, host, port, user, password, database):
        self.host = host
        self.port = port
        self.user = user
        self.password = password
        self.database = database

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            host=crawler.settings.get("MYSQL_HOST"),
            port=crawler.settings.get("MYSQL_PORT"),
            user=crawler.settings.get("MYSQL_USER"),
            password=crawler.settings.get("MYSQL_PASSWORD"),
            database=crawler.settings.get("MYSQL_DB"),
        )

    def open_spider(self, spider):
        # 鏈接數(shù)據(jù)庫
        self.db = pymysql.connect(host=self.host,
                                  port=self.port,
                                  user=self.user,
                                  password=self.password,
                                  db=self.database,
                                  charset='utf8')
        self.cursor = self.db.cursor()

    def close_spider(self, spider):
        self.db.close()

    def process_item(self, item, spider):
        sql = "insert into biquge(content, name) values(('%s'),('%s'))" % (item['content'], item['name'])
        print(sql)
        self.cursor.execute(sql)
        self.db.commit()
        return item

注意:下面?zhèn)z種寫法

from TestSpider.settings import MongoDB_HOST, MongoDB_PORT, MongoDB_PASSWORD, MongoDB_DB
@classmethod
    def from_crawler(cls, crawler):
        # 返回mongodbpipeline對象
        return cls(
            mongo_host=MongoDB_HOST,
            mongo_port=MongoDB_PORT,
            mongo_password=MongoDB_PASSWORD,
            mongo_db = MongoDB_DB
        )
@classmethod
    def from_crawler(cls, crawler):
        return cls(
            host=crawler.settings.get("MYSQL_HOST"),
            port=crawler.settings.get("MYSQL_PORT"),
            user=crawler.settings.get("MYSQL_USER"),
            password=crawler.settings.get("MYSQL_PASSWORD"),
            database=crawler.settings.get("MYSQL_DB"),
        )


    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            MYSQL_HOST,
            MYSQL_PORT,
            MYSQL_USER,
            MYSQL_PASSWORD,
            MYSQL_DB,
        )
    
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晤揣,隨后出現(xiàn)的幾起案子桥爽,更是在濱河造成了極大的恐慌,老刑警劉巖昧识,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钠四,死亡現(xiàn)場離奇詭異,居然都是意外死亡跪楞,警方通過查閱死者的電腦和手機缀去,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來习霹,“玉大人朵耕,你說我怎么就攤上這事×芤叮” “怎么了阎曹?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長煞檩。 經(jīng)常有香客問我处嫌,道長,這世上最難降的妖魔是什么斟湃? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任熏迹,我火速辦了婚禮,結果婚禮上凝赛,老公的妹妹穿的比我還像新娘注暗。我一直安慰自己,他們只是感情好墓猎,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布捆昏。 她就那樣靜靜地躺著,像睡著了一般毙沾。 火紅的嫁衣襯著肌膚如雪骗卜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音寇仓,去河邊找鬼举户。 笑死,一個胖子當著我的面吹牛遍烦,可吹牛的內(nèi)容都是我干的俭嘁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼乳愉,長吁一口氣:“原來是場噩夢啊……” “哼兄淫!你這毒婦竟也來了?” 一聲冷哼從身側響起蔓姚,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤捕虽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后坡脐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泄私,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年备闲,在試婚紗的時候發(fā)現(xiàn)自己被綠了晌端。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡恬砂,死狀恐怖咧纠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泻骤,我是刑警寧澤漆羔,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站狱掂,受9級特大地震影響演痒,放射性物質發(fā)生泄漏。R本人自食惡果不足惜趋惨,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一鸟顺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧器虾,春花似錦讯嫂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挤悉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背装悲。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工昏鹃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诀诊。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓洞渤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親属瓣。 傳聞我的和親對象是個殘疾皇子载迄,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容