scarpy--使用pipeline模块 同步和异步写数据库

1.同步爬取存储数据:

pipeline用于专门处理要抓取的域。

scrapy可以通过pipeline模块来保存数据。在pipeline.py中已经默认创建了一个pipeline类,创建一个新的pipeline类用于处理数据,并将数据保存到MySQL。

pipeline 类会在 process_item 方法中处理数据,然后在结束时调用 close_spider 方法,因此我们 
需要自定义这两个方法做相应的处理。

注意:
  • 在 process_item() 方法处理完成后要返回 item 供后面的 Pipeline 类继续操作
  • 在__init__()方法中做一些实例化时需要的操作
  • 记得在 close_spider() 中释放资源

class MysqlPipeline(object):
    """
    自定义将数据写入数据库
    """
    def __init__(self):
        self.conn = MySQLdb.connect(host="127.0.0.1", user="root", password="123456", db="article_spider", charset="utf8",
                                    use_unicode=True)
        self.cursor = self.conn.cursor()   # 实例化游标

    def process_item(self, item, spider):
        insert_sql = """insert into jobbole_article(title, url, create_date, fav_nums)
                        values (%s, %s, %s, %s)"""
        # 使用`占位符
        self.cursor.execute(insert_sql, (item["title"], item["url"], item["create_date"], item["fav_nums"]))
        # commit()才会提交到数据库
        self.conn.commit()

    def close_spider(self, spider):
        self.cursor.close()
        self.conn.close()

之后需要在setting.py文件中进行配置文件

ITEM_PIPELINES = {
    
'ArticelSpider.pipelines.MysqlPipeline': 1,
}

2.异步爬取存储数据:

上面的 Pipeline 类虽然可以将数据写在 MySQL 数据中,但是在 Scrapy 对数据的处理是同步执行的,当爬取数据量很大的时候,会出现插入数据的速度跟不上网页的爬取解析速度,造成阻塞,为了解决这个问题需要将 MySQL 的数据存储异步化。Python 中提供了 Twisted 框架来实现异步操作,该框架提供了一个连接池,通过连接池可以实现数据插入 MySQL 的异步化。

下面是集合 Twisted 框架实现的 Pipeline 类,可以完成 MySQL 的异步化操作:

这里使用的是 MySQLdb 模块,在初始化 Pipeline 的时候,通过参数创建数据库连接池 dbpool, 

然后在 process_item 方法中来对连接池进行配置,执行其执行方法和数据。这里我们没有写出上面例子中出现的 SQL 语句,而是将其封装到了具体的 Item类中,这样我们的 Pipeline 类可以处理各种不同的数据。

另外在配置文件中进行了如下配置:

MYSQL_HOST = "127.0.0.1"
MYSQL_DBNAME = "article_spider"  # 数据库名称 非表名称 表名称会在sql语句中指明
MYSQL_USER = "root"
MYSQL_PASSWORD = "123456"
这样在调用时则需要 

@classmethod
    def from_settings(cls, settings):  
        host = settings["MYSQL_HOST"]
即可取出 上面是固定的写法。当然也可以直接进行卸载函数内部,此处不再放码 参见链接,不过以上更方便管理。



class MysqlTwistedPipeline(object):
    # 采用异步机制写入MySQL
    def __init__(self, dppool):
        self.dppool = dppool

    # 用固定方法 【写法固定】  获取配置文件内信息
          @classmethod
    def from_settings(cls, settings):   # cls实际就是本类 MysqlTwistedPipeline
        dpparms = dict(
        host = settings["MYSQL_HOST"],
        db = settings["MYSQL_DBNAME"],
        user = settings["MYSQL_USER"],
        passwd = settings["MYSQL_PASSWORD"],
        charset = "utf8",
        cursorclass = MySQLdb.cursors.DictCursor, # 指定 curosr 类型  需要导入MySQLdb.cursors
        use_unicode = True
        )  # 由于要传递参数 所以参数名成要与connnect保持一致
            # 用的仍是MySQLdb的库 twisted并不提供
                # 异步操作
                # adbapi # 可以将MySQLdb的一些操作变成异步化操作
                dppool = adbapi.ConnectionPool("MySQLdb", **dpparms) # 告诉它使用的是哪个数据库模块  连接参数
                # 另外 以上dpparms的参数也可单独写,这样会造成参数列表过大

                return cls(dppool)  # 即实例化一个pipeline

    def process_item(self, item, spider):
        # 使用twistedmysql插入编程异步操作
                  # 指定操作方法和操作的数据 [下面会将方法异步处理]
        query = self.dppool.runInteraction(self.do_insert, item)
        # AttributeError: 'Deferred' object has no attribute 'addErrorback'
        # query.addErrorback(self.handle_error)  # 处理异常
                  query.addErrback(self.handle_error)  # 处理异常


         def handle_error(self, failure, item, spider):
        # 定义错误 处理异步插入的异常
                  print(failure)


    def do_insert(self, cursor, item):
        """
        此类内其他都可以看作是通用 针对不同的sql操作只需要改写这里即可了
                   :param cursor:
        :param item:
        :return:
        """
        insert_sql = """insert into jobbole_article(title, url, create_date, fav_nums)
                                values (%s, %s, %s, %s)"""
        # 使用`占位符
                  cursor.execute(insert_sql, (item["title"], item["url"], item["create_date"], item["fav_nums"]))
do_insert

do_insert方法指定要操作的数据语句,其他不用过多修改,只需在此处编写语句 就可以异步执行操作。

本文章的编写部分 参考:Scrapy 入门笔记(4) --- 使用 Pipeline 保存数据





 


scrapy-redis是基于redis的分布式组件,它是scrapy框架的一个组件。它的主要作用是实现断点续爬和分布式爬虫的功能。 使用scrapy-redis可以实现分布式数据处理,爬取到的item数据可以被推送到redis中,这样你可以启动尽可能多的item处理程序。 安装和使用scrapy-redis非常简单,一般通过pip安装Scrapy-redis:pip install scrapy-redis。同scrapy-redis需要依赖Python 2.7, 3.4 or 3.5以上,Redis >= 2.8和Scrapy >= 1.1。在使用,你只需要做一些简单的设置,几乎不需要改变原本的scrapy项目的代码。 scrapy-redis将数据存储在redis中,你可以在redis中查看存储的数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [scrapy_redis的基本使用和介绍](https://blog.csdn.net/WangTaoTao_/article/details/107748403)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [爬虫学习笔记(十二)—— scrapy-redis(一):基本使用、介绍](https://blog.csdn.net/qq_46485161/article/details/118863801)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值