续上一篇的scrapy入门案例的基于终端命令的持久化方式,这篇文章主要讲解,基于管道的持久化保存到本地和MySQL数据库,
主要流程:
1. 数据解析
在main.py文件下,
def parse(self, response):
all_data = []
title_list = response.xpath('/html/body/div[2]/div[1]/main/div/ul/li/a')
for title in title_list:
src = title.xpath('./@href')[0].extract()
chapter = title.xpath('./text()')[0].extract()
# 向详情页发送url请求
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.197.400 QQBrowser/11.6.5265.400'
}
detail = requests.get(url=src, headers=headers)
# 对爬取的内容进行再次编码
detail.encoding = 'utf-8'
detail_text = detail.text
detail_soup = BeautifulSoup(detail_text, 'lxml')
content = detail_soup.find('div', class_='grap').text
2. 在item类中定义相关的属性
在items.py文件下,
import scrapy
class Exercise01Item(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
chapter = scrapy.Field()
content = scrapy.Field()
3. 将解析的数据封装存储到item类型的对象,将item类型的对象提交给管道进行持久化存储的操作
在main.py文件的parse方法内部,
# 实例化一个item对象
item = Exercise01Item()
item['chapter'] = chapter
item['content'] = content
# 将item对象提交给管道
yield item
4. 在管道类的process_item中要将其接受到的item对象中存储的数据进行持久化存储操作
在pipeline.py文件中,分别将文件保存在本地和MySQL,需要在mysql中建一个叫novels数据库,创建一个novels表,内含一个chapter字段和content字段,其中,Exercise01Pipeline类是将文件保存到本地的novels.txt文件,MysqlPipeLine类是将文件保存到MySQL端的novels数据库的novels表中。
import pymysql
class Exercise01Pipeline:
fp = None
# 重写父类的一个方法:爬虫开始前执行一次,创建并打开文件
def open_spider(self, spider):
self.fp = open('./novels.txt', 'w', encoding='utf-8')
print('正在爬取文件到本地...')
def process_item(self, item, spider):
self.fp.write(item['chapter'] + ':' + item['content'] + '\n')
print(item['chapter'], '在本地爬取成功!')
return item
# 爬虫完成后执行一次,关闭文件
def close_spider(self, spider):
self.fp.close()
print('文件爬取成功!')
class MysqlPipeLine(object):
connect = None
cursor = None
def open_spider(self, spider):
self.connect = pymysql.Connect(host='127.0.0.1', user='root', password='root', database='novels', port=3306, charset='utf8')
print('正在爬取文件到mysql数据库...')
def parse(self, item, spider):
self.cursor = self.connect.cursor()
# 执行sql语句,事务管理
try:
chapter = pymysql.escape_string(item['chapter'])
content = pymysql.escape_string(item['content'])
self.cursor.execute('insert into novels values ("%s","%s")' % (chapter, content))
self.connect.commit()
print(item['chapter'], '在mysql数据库中插入成功!')
except Exception as e:
print(e)
self.connect.rollback()
return item
def close_spider(self, spider):
self.connect.close()
# self.cursor.close()
print('文件在mysql数据库中插入完成!')
5. 在配置文件中开启管道
在settings.py文件中,
# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
"exercise01.pipelines.Exercise01Pipeline": 300,
"exercise01.pipelines.MysqlPipeLine": 301
}