python持久化存储_python爬虫之爬虫数据持久化保存

1.items.py文件:自定义字段,确定要爬取的目标网站数据

import scrapy

class DoubanItem(scrapy.Item):

# 标题

title = scrapy.Field()

# 是否可播放的状态

playable = scrapy.Field()

# 简介

content = scrapy.Field()

# 评分

star = scrapy.Field()

# 评论数量

commentnum = scrapy.Field()

# 主题

inq = scrapy.Field()

2.spiders/douban.py 文件: 爬虫文件,在这里编写爬虫代码,解析数据,获取新的url

import scrapy

from douban.items import DoubanItem

class DoubanspiderSpider(scrapy.Spider):

name = 'doubanspider'

allowed_domains = ['douban.com']

#可以设置偏移量,也可以提取网站页面源码中下一页

#标签的链接,获取到下一页url地址

offset = 0

url = 'https://movie.douban.com/top250?start='

start_urls = [url + str(offset) + "&filter="]

def parse(self, response):

itemlist = response.xpath("//div[@class='item']")

for each in itemlist:

item = DoubanItem()

# 标题

title = each.xpath(".//div[@class='info']/div[@class='hd']//span[@class='title']/text()").extract_first("")

# 是否可播放的状态

playable = each.xpath(".//div[@class='info']/div[@class='hd']/span[@class='playable']/text()").extract_first("")

# 简介

content = each.xpath(".//div[@class='info']//div[@class='bd']/p/text()").extract()

content = "".join(content).strip()

# 评分

star = each.xpath(".//div[@class='star']//span[@class='rating_num']/text()").extract_first("")

# 评论数量

commentnum = each.xpath(".//div[@class='star']/span[4]/text()").extract_first("")

# 主题

inq = each.xpath(".//div[@class='info']//div[@class='bd']//span[@class='inq']/text()").extract_first("")

item['title'] = title

item['playable'] = playable

item['content'] = content

item['star'] = star

item['commentnum'] = commentnum

item['inq'] = inq

yield item

#下一页(方式一)

if self.offset < 250:

self.offset += 25

yield scrapy.Request(self.url + str(self.offset) +"&filter=",callback= self.parse)

3.数据持久化

方式一:将数据存入mongodb

settings.py文件: 设置文件,在这里设置User-Agent,激活管道文件等...

ITEM_PIPELINES = {

'douban.pipelines.DoubanPipeline': 300,

}

MONGODB 主机名

MONGODB_HOST = '127.0.0.1'

MONGODB 端口号

MONGODB_PORT= 27017

数据库名称

MONGODB_DBNAME = "Douban"

存储数据的表名称

MONGODB_SHEETNAME= "doubanmovies"

4.pipelines.py管道:这里进行数据的清洗和持久化

import pymongo

from scrapy.conf import settings

class DoubanPipeline(object):

# 将数据存储在mongodb中

def __init__(self,host,port,dbname,sheetname):

# 创建MONGODB数据库链接

client = pymongo.MongoClient(host=host, port=port)

# 指定数据库

mydb = client[dbname]

# 存放数据的集合名称

self.mysheet = mydb[sheetname]

@classmethod

def from_crawler(cls, crawler):

host = crawler.settings["MONGODB_HOST"]

port = crawler.settings["MONGODB_PORT"]

dbname = crawler.settings["MONGODB_DBNAME"]

sheetname = crawler.settings["MONGODB_SHEETNAME"]

return cls(host,port,dbname,sheetname)

def process_item(self,item,spider):

data = dict(item)

# mongodb数据插入语句,使用save保存数据的效率会很慢,因为它需要循环便利,操作费时

self.mysheet.insert(data)

return item

方式二:将数据存入mysql数据库

settings.py文件: 设置文件,在这里设置User-Agent,激活管道文件等...

ITEM_PIPELINES = {

'douban.pipelines.DoubanPipeline': 300,

}

#关于数据库的相关配置

MYSQL_HOST = '127.0.0.1'

MYSQL_PORT = 3306

MYSQL_USER = ''

MYSQL_PWD = ''

MYSQL_DB = ''

pipelines.py管道文件

import pymysql

class DoubanPipeline(object):

# 将数据存储值mysql数据库

# _mysql_exceptions.OperationalError: (1366, 是因为数据库中的字符集与charset="utf8"不符合

def __init__(self,host,port,user,pwd,db,charset):

self.client = pymysql.Connect(host,user,pwd,db,port,charset='utf8')

self.cursor = self.client.cursor()

@classmethod

def from_crawler(cls,crawler):

host = crawler.settings['MYSQL_HOST']

port = crawler.settings['MYSQL_PORT']

user = crawler.settings['MYSQL_USER']

pwd = crawler.settings['MYSQL_PWD']

db = crawler.settings['MYSQL_DB']

return cls(host,port,user,pwd,db,charset)

def process_item(self,item,spider):

insert_sql = """

insert into doubanmovie(title, playable, content, star, commentnum, inq)

VALUE (%s, %s, %s, %s, %s, %s)

"""

try:

self.cursor.execute(insert_sql, (item['title'], item['content'], item['score'], item['info']))

self.client.commit()

except Exception as err:

print(err)

self.client.rollback()

return item

5.思考???: 在pipeline中我们进行数据插入,如何解耦?

将sql语句和要插入的数据在item中定义一个方法返回,通过item调用,然后返回

class XxxxItem(scrapy.Item):

#名称

title = scrapy.Field()

def insert_data_to_db(self,dataDict):

sql = """

INSERT INTO caipu (%s)

VALUES (%s)

""" % (','.join(dataDict.keys()),','.join(['%s']*len(dataDict)))

data = list(dataDict.values())

return sql,data

mysql数据异步插入

settings.py配置文件

#将mysql相关信息写在settings中

MYSQL_HOST = '127.0.0.1'

MYSQL_ROOT = '数据库用户名'

MYSQL_PASSWORD = '数据库密码'

MYSQL_DBNAME = 'DouBan'

6.异步插入数据库

import pymysql

#twisted是一个异步的网络框架,这里可以帮助我们

实现异步将数据插入数据库

#adbapi里面的子线程会去执行数据库的阻塞操作,

当一个线程执行完毕之后,同时,原始线程能继续

进行正常的工作,服务其他请求。

from twisted.enterprise import adbapi

#异步插入数据库

class DoubanPipeline(object):

def __init__(self,dbpool):

self.dbpool = dbpool

#使用这个函数来应用settings配置文件。

@classmethod

def from_crawler(cls, crawler):

parmas = {

'host':crawler.settings['MYSQL_HOST'],

'user':crawler.settings['MYSQL_USER'],

'passwd':crawler.settings['MYSQL_PASSWD'],

'db':crawler.settings['MYSQL_DB'],

'port':3306,

'charset':'utf8',

}

# **表示字典,*tuple元组,

# 使用ConnectionPool,起始最后返回的是一个ThreadPool

dbpool = adbapi.ConnectionPool(

'pymysql',

**parmas

)

return cls(dbpool)

def process_item(self, item, spider):

#这里去调用任务分配的方法

query = self.dbpool.runInteraction(

self.insert_data_todb,

item,

spider

)

#数据插入失败的回调

query.addErrback(

self.handle_error,

item

)

#执行数据插入的函数

def insert_data_todb(self,cursor,item,spider):

insert_str,parmas = item.insertdata()

cursor.execute(insert_str,parmas)

print('插入成功')

def handle_error(self,failure,item):

print(failure)

print('插入错误')

#在这里执行你想要的操作

def close_spider(self, spider):

self.pool.close()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值