day08-scrapy中间件重写和数据库连接

  • scrapy执行逻辑详细图


    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,表示继续执行其他中间件的process_request方法
        #       如果最后一个中间件的process_request方法还是返回None,
        #       则表示取调用下载器进行下载请求
        return None

        # 返回Response, 表示不去调用下载器进行下载请求,
        #           而是直接返回响应内容给解析方法parse(response)
        # return Response(url='http://www.baidu.com', body='12345')

        # 返回Request,表示发送请求给调度器进行下载,不建议使用
        # 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):
        # 修改响应内容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的内容
                # 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. 连接数据库

链接数据库准备

  • 在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内容时,可以对结果进行处理,在返回实体
        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参数
# Mongo配置
MongoDB_HOST = '127.0.0.1'
MongoDB_PORT = 27017
MongoDB_PASSWORD = '123456'
MongoDB_DB = 'spider'
  • piplines数据库连接

class MongoDBPipeline():
    # 持久化数据
    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数据保存在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参数
# msyql配置
MYSQL_HOST = '127.0.0.1'
MYSQL_PORT = 3306
MYSQL_PASSWORD = '960218'
MYSQL_USER = 'root'
MYSQL_DB = 'spider'
  • piplines数据库连接

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):
        # 链接数据库
        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

注意:下面俩种写法

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,
        )
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容