Scrapy是一个用于爬取网页并提取数据的Python框架。在爬取数据后,我们需要把数据保存到数据库中进行后续处理,使其更方便的进行分析和应用。Scrapy支持将数据存储到多种不同类型的数据库中,其中包括MySQL。在MySQL数据库中,Scrapy数据存储的主要方式是同步和异步。
- 同步方式
同步方式是指将数据存储到MySQL数据库时,采用常规的同步方式,遵循线性执行的方式,即一条SQL语句执行完后再执行下一条。在Scrapy中,同步方式的存储使用的是MySQLdb库和pymysql库。具体步骤如下:
- 下载MySQLdb库或pymysql库:
pip install MySQL-python
或
pip install PyMySQL
- 配置数据库信息
在Scrapy配置文件中配置数据库信息。比如在settings.py中,配置MySQL数据库信息和相关的处理程序:
MYSQL_HOST = 'localhost'
MYSQL_DBNAME = 'scrapy_db'
MYSQL_USER = 'root'
MYSQL_PASSWORD = '123456'
ITEM_PIPELINES = {
'myproject.pipelines.SyncMySQLPipeline': 300,
}
- 定义Pipeline
在Scrapy项目中,定义数据存储Pipeline。在Pipeline中,定义process_item函数,连接到数据库并执行SQL语句。
import MySQLdb
class SyncMySQLPipeline(object):
def __init__(self):
self.db = MySQLdb.connect(
host=settings['MYSQL_HOST'],
db=settings['MYSQL_DBNAME'],
user=settings['MYSQL_USER'],
passwd=settings['MYSQL_PASSWORD'],
charset='utf8',
use_unicode=True
)
self.cursor = self.db.cursor()
def process_item(self, item, spider):
sql = "insert into table_name(col1, col2, col3) values('%s', '%s', '%s')"%(item['col1'], item['col2'], item['col3'])
self.cursor.execute(sql)
self.db.commit()
return item
- 执行Scrapy爬虫
在命令行中执行Scrapy爬虫:
scrapy crawl spider_name
- 异步方式
异步方式是指将数据存储到MySQL数据库时,采用异步方式,不遵循线性执行的方式。在Scrapy中,异步方式的存储使用的是Twisted库。具体步骤如下:
- 下载Twisted库:
pip install Twisted
- 配置数据库信息
在Scrapy配置文件中配置数据库信息。比如在settings.py中,配置MySQL数据库信息和相关的处理程序:
MYSQL_HOST = 'localhost'
MYSQL_DBNAME = 'scrapy_db'
MYSQL_USER = 'root'
MYSQL_PASSWORD = '123456'
ITEM_PIPELINES = {
'myproject.pipelines.AsyncMySQLPipeline': 300,
}
- 定义Pipeline
在Scrapy项目中,定义数据存储Pipeline。在Pipeline中,定义__init__函数和process_item函数,连接到数据库。
from twisted.enterprise import adbapi
import MySQLdb
class AsyncMySQLPipeline(object):
def __init__(self):
self.dbpool = adbapi.ConnectionPool(
'MySQLdb',
host=settings['MYSQL_HOST'],
db=settings['MYSQL_DBNAME'],
user=settings['MYSQL_USER'],
passwd=settings['MYSQL_PASSWORD'],
charset='utf8',
use_unicode=True
)
def process_item(self, item, spider):
query = self.dbpool.runInteraction(self._insert, item)
query.addErrback(self._handle_error)
return item
def _insert(self, tx, item):
sql = "insert into table_name(col1, col2, col3) values('%s', '%s', '%s')"%(item['col1'], item['col2'], item['col3'])
tx.execute(sql)
def _handle_error(self, failure):
print(failure)
- 执行Scrapy爬虫
在命令行中执行Scrapy爬虫:
scrapy crawl spider_name
示例说明:
假设我们要爬取豆瓣电影Top 250的电影信息,并将其存储到MySQL数据库中。这里以同步方式为例。
- 先根据需要定义Item:
import scrapy
class DoubanMovieItem(scrapy.Item):
movie_name = scrapy.Field()
movie_score = scrapy.Field()
movie_director = scrapy.Field()
- 编写Spider
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['movie.douban.com']
start_urls = ['https://movie.douban.com/top250']
def parse(self, response):
item = DoubanMovieItem()
movies = response.xpath('//ol[@class="grid_view"]/li')
for movie in movies:
item['movie_name'] = movie.xpath('.//span[@class="title"]/text()').extract_first()
item['movie_score'] = movie.xpath('.//span[@class="rating_num"]/text()').extract_first()
item['movie_director'] = movie.xpath('.//p[@class=""]/text()[1]')
yield item
- 定义Pipeline
import MySQLdb
class SyncMySQLPipeline(object):
def __init__(self):
self.db = MySQLdb.connect(
host=settings['MYSQL_HOST'],
db=settings['MYSQL_DBNAME'],
user=settings['MYSQL_USER'],
passwd=settings['MYSQL_PASSWORD'],
charset='utf8',
use_unicode=True
)
self.cursor = self.db.cursor()
def process_item(self, item, spider):
sql = "insert into douban_movie(movie_name, movie_score, movie_director) values('%s', '%s', '%s')"%(item['movie_name'], item['movie_score'], item['movie_director'])
self.cursor.execute(sql)
self.db.commit()
return item
- 执行Scrapy爬虫
在命令行中执行Scrapy爬虫:
scrapy crawl douban
这样即可将豆瓣电影Top 250的电影信息存储到MySQL数据库中。
另外,对于异步方式的存储,只需要将Pipeline中的AsyncMySQLPipeline类替换为前面的SyncMySQLPipeline类,不需要修改其他任何代码。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:scrapy数据存储在mysql数据库的两种方式(同步和异步) - Python技术站