scrapy爬虫系列:利用pymysql操作mysql数据库
发布于 作者:苏南大叔 来源:程序如此灵动~苏南大叔在本篇文章中,继续讲述scrapy
如何处理item
数据,如何把抓取到的item
数据,持久化到mysql
数据库之中。
本文的主要战场是:piplines.py
这个文件。在python
中,配合mysql
的库文件也有好多个。本文中涉及的,也是个非常基础的python
库,名字叫做:pymysql
。
本文的测试环境是:python3.7
,scrapy1.5.1
,pymysql0.9.2
。本文中涉及的item
,都是指:爬虫yield item
返回来的item
。
安装pymysql
要使用pymysql
,就需要先通过pip
安装pymysql
,安装pymysql
的方法如下:
pip install pymysql
可以查看到安装好的pymsql
版本号是0.9.2
。
pip show pymysql
引入pymysql
包
苏南大叔计划是在piplines.py
中使用pymysql
,所以在这个.py
文件的顶部,引入了pymysql
的包。
import pymysql
建立数据库链接
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
通过pymysql
把item
数据,持久化成了mysql
里面的一条条记录。当然pymysql
并不是这期间最好最优的选择。在python
的世界里面,用于操作mysql
数据库的库非常多。这里,就仅仅做个抛砖引玉了。
到本教程为止,应该可以使用scrapy
应对一般的数据抓取任务了。当然,更多更详细的scrapy
的经验文章,苏南大叔正在不断准备中,敬请期待。
那么想知道,其它的python
操作数据库的其它方式么?那么,请关注苏南大叔的后续python
系列文章。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。