我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

苏南大叔在本篇文章中,继续讲述scrapy如何处理item数据,如何把抓取到的item数据,持久化到mysql数据库之中。

本文的主要战场是:piplines.py这个文件。在python中,配合mysql的库文件也有好多个。本文中涉及的,也是个非常基础的python库,名字叫做:pymysql

苏南大叔:scrapy爬虫系列:利用pymysql操作mysql数据库 - scrapy-pymysql
scrapy爬虫系列:利用pymysql操作mysql数据库(图4-1)

本文的测试环境是:python3.7scrapy1.5.1pymysql0.9.2。本文中涉及的item,都是指:爬虫yield item返回来的item

安装pymysql

要使用pymysql,就需要先通过pip安装pymysql,安装pymysql的方法如下:

pip install pymysql

苏南大叔:scrapy爬虫系列:利用pymysql操作mysql数据库 - pip_install_pymysql
scrapy爬虫系列:利用pymysql操作mysql数据库(图4-2)

可以查看到安装好的pymsql版本号是0.9.2

pip show pymysql

苏南大叔:scrapy爬虫系列:利用pymysql操作mysql数据库 - pip_show_pymysql
scrapy爬虫系列:利用pymysql操作mysql数据库(图4-3)

引入pymysql

苏南大叔计划是在piplines.py中使用pymysql,所以在这个.py文件的顶部,引入了pymysql的包。

import pymysql

苏南大叔:scrapy爬虫系列:利用pymysql操作mysql数据库 - import_pymysql
scrapy爬虫系列:利用pymysql操作mysql数据库(图4-4)

建立数据库链接

piplines.py中的某个pipline中,在__init__()阶段初始化pymyql的链接。

class DemoPipeline(object):
    def __init__(self):
        self.connect = pymysql.connect(
            host= "127.0.0.1",
            db="db_name",
            user="root",
            passwd="root",
            charset='utf8',
            use_unicode=True,
            cursorclass=pymysql.cursors.DictCursor
        )
        # 通过cursor执行增删查改
        self.cursor = self.connect.cursor();
        # self.connect.close();
        # self.cursor.close(); 

这里的数据库参数配置,就不多说了。大家都会配置。着重就说一下下面两个要点:

  • cursorclass=pymysql.cursors.DictCursor,这个很重要,涉及到mysql的查询结构返回值的读取方式。目前为止,大家就仅仅需要知道,设置为pymysql.cursors.DictCursor的话,就会更加符合我们的操作习惯,就可以了。
  • self.cursor,这个更加重要,就是相当于大家写php的时候的db对象。各种查询,都是在这个self.cursor的基础上,继续点出来的。
  • self.connect.close()self.cursor.close(),大家可以不写,或者写到close_spider(self, spider)事件里面。反正,大家找个合适的地方放就行了,没有合适的地方不写也行。

执行sql语句

不管是增删改查的那一步,都是执行sql语句。所以,下面这条语句self.cursor.execute(),其实是万能的。

self.cursor.execute("""truncate table wp_posts""");
self.cursor.execute("""truncate table %s""","wp_posts");
self.cursor.execute("""truncate table %s""",("wp_posts"));
# self.connect.commit();

套路上非常简单,要点如下:

  • """,三个连续英文分号。
  • %s,这个是防止字符串拼接的,大家都懂。
  • %s的真实值,放在execute()的第二个参数位置。如果仅有一个%s,那么就可以直接写值。如果有多个,那么就可以用()把所有的值,转化成一个占位。
  • self.connect.commit(),触发真实的sql执行。
  • 这个sql如何太长的话,可以折行写的。
  • %s占位,外面没有任何符号包裹的,仅一个空的%s,写上大家认为中的单引号的话,是会报错的。

插入数据

插入数据的sql语句,就是一个简单的insert语句,大家注意使用%s占位即可。
self.cursor.lastrowid,这个是取得插入id的方式。很重要,很常用。

self.cursor.execute(
    """insert into wp_posts(
        post_author,post_date,
        post_date_gmt
    )value (
        1, %s, 
        %s
    )""",
    (
        item['author'], dtime, 
        dtime2
    ))
self.connect.commit()
post_id = self.cursor.lastrowid

更新数据

下面是一条更新update的范例demo,self.cursor.rowcount是指影响的行数。

self.cursor.execute("""update baidu set content=%s where href = %s""",
    (item['content'],item['href']))
self.connect.commit()
print (self.cursor.rowcount)

删除数据

下面是一条更新update的范例demo,self.cursor.rowcount是指被影响的行数。

self.cursor.execute("""delete from wp_posts where id<=%s""", (5))
self.connect.commit()
print(self.cursor.rowcount)

查询数据

查询数据的时候,可能出问题的概率比较大。那么需要注意的是,如何拿到数据。

  • fetchone()/fetchall()/fetchmany(),其中fetchone()fetchall()比较常用。
  • 那么请注意在初始化阶段的参数cursorclass=pymysql.cursors.DictCursor。否则返回值不是字典类型,而是元组类型。没有key,可能导致你无所适从。
self.connect = pymysql.connect(
    # ...
    cursorclass=pymysql.cursors.DictCursor
    # ...
)
self.cursor.execute("""SELECT * from wp_posts where id = %s""", (5))
result = self.cursor.fetchone()
if result:
    title = result["title"]

这里先做简要说明,后续再展开文章讨论fetchone()/fetchall()/fetchmany()的具体区别及用法。

结论

scrapy通过pymysqlitem数据,持久化成了mysql里面的一条条记录。当然pymysql并不是这期间最好最优的选择。在python的世界里面,用于操作mysql数据库的库非常多。这里,就仅仅做个抛砖引玉了。

到本教程为止,应该可以使用scrapy应对一般的数据抓取任务了。当然,更多更详细的scrapy的经验文章,苏南大叔正在不断准备中,敬请期待。

那么想知道,其它的python操作数据库的其它方式么?那么,请关注苏南大叔的后续python系列文章。

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   mysql    python