scrapy+baiduapi搭建一个私人小说阅读器(智能爬取加智能朗读)(一)
2021-01-18 03:11
标签:sea lan 中间件 ide 阅读 latest print callback str 喜欢看小说,平时都是通过电脑或者手机看小说,手机听小说(智能语音),或者喜马拉雅搜索小说听(好多喜欢的都收费o(╥﹏╥)o,然后网上好多免费资源却不能听),想在电脑上听小说,目前Microsoft Edge可以阅读网页文本很赞,不能自动翻译很烦(# ̄~ ̄#),而且智能语音库体验很差,所以想一个能搜索网上资源智能朗读的东东,木有发现好的,就自己写一个吧! (Microsoft Edge阅读视图朗读示例) 1.scrapy环境搭建,这里就不说了,网上资源一堆,我也收录了一个,不知道可以看看,附带一个scrapy经典的架构图(转载) 2.核心代码编写,按照爬虫架构,来编写爬虫及各个中间件内容(见代码) 爬虫核心代码(BiqugeSpider),最高爬取深度4层,同时定义了关键字和全文爬取2种策略 第1层 根据关键字搜索小说列表(默认函数parse),这里主要根据获取分页所有页url,传递给下一层,小说的基本信息列表爬取层 代码如下(这里xpath就不做介绍了,有兴趣自己学习下): 第2层 根据小说基本信息列表获取每本小说的详情url,传递给下一层,小说基本信息爬取层 图和第一层类似,这里省略 代码如下: 第3层 根据小说分页列表获取每本检索到小说的基本信息,同时获取章节列表url,传递给下一层,小说内容爬取层 代码如下:(存储了小说的名称、作者、简介信息) 第4层 根据小说章节url获取小说内容信息,存储小说内容,到此,小说内容全部爬取完成 代码如下: 3.持久化处理 上面说到了爬虫的内容怎么获取,下面说到存储,当然这层可以自己处理,这里为了方便使用腾讯云mysql进行存储小说信息(mysql帮助类) 数据库和表结构初始化: 小说基本信息存储代码: 小说内容信息存储代码: 数据库存储结果: (小说基本信息) (小说内容信息) 4.代码地址 只能朗读客户端下一章继续写,代码github地址先附上 scrapy+baiduapi搭建一个私人小说阅读器(智能爬取加智能朗读)(一) 标签:sea lan 中间件 ide 阅读 latest print callback str 原文地址:https://www.cnblogs.com/comicwang/p/12187377.html写在前面的话
小说资源获取(scrapy爬虫获取biquge资源)
用来处理整个系统的数据流处理, 触发事务(框架核心)
用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。
介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。
介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。
def parse(self, response):
index=0
#检索小说(这里通过判断关键字来进行全文或者关键字爬取)
if self.p:
for each in response.xpath("//*[@class=‘search-result-page-main‘]/a"):
src=each.attrib[‘href‘]
yield scrapy.Request(self.domainUrl+ src, callback = self.ParsePage,dont_filter=False)
else:
for each in response.xpath("//*[@id=‘main‘]/div[1]/ul/li"):
if index>0:
src=each.xpath(".//span[2]/a")[0].attrib[‘href‘]
yield scrapy.Request(self.domainUrl+ src, callback = self.BookBasic,dont_filter=False)
index=index+1
#获取分页内容,进行关键字深度爬取
def ParsePage(self,response):
for each in response.xpath("//*[@class=‘result-list‘]/div"):
src=each.xpath(".//div/a")[0].attrib[‘href‘]
yield scrapy.Request(self.domainUrl+ src, callback = self.BookBasic,dont_filter=False)
#获取小说基本信息,同时让调度器爬取小说内容
def BookBasic(self,response):
Id=uuid.uuid1()
BookName=response.xpath("string(//*[@id=‘info‘]/h1)")[0].root.strip()
Author=response.xpath("string(//*[@id=‘info‘]/p)")[0].root.strip().split(‘:‘)[1]
imgSrc=response.xpath("//*[@id=‘fmimg‘]/img")[0].attrib[‘src‘]
img= requests.get(imgSrc)
Image= img.content
LatestChapter=response.xpath("string(//*[@id=‘info‘]/p[4]/a)")[0].root.strip()
Desc1=response.xpath("string(//*[@id=‘intro‘])")[0].root.strip()
#查询小说是否存在
resp= self.mysql.Query("select Id from BookBasic where BookName=‘{0}‘".format(BookName))
if not resp:
# 获取小说信息
Id=uuid.uuid1()
#插入数据
self.mysql.ExecuteSql("insert into BookBasic (BookName,Author,Image,LatestChapter,Desc1,Id) values(%s,%s,%s,%s,%s,%s)",(str(BookName),str(Author),Image,str(LatestChapter),str(Desc1),str(Id)))
else:
Id=resp[0][0]
self.mysql.ExecuteSql("update BookBasic set LatestChapter=%s,Desc1=%s where Id=%s",(str(LatestChapter),str(Desc1),str(Id)))
#查询所有章节
list=self.mysql.Query("select Title from BookContent where Id=‘{0}‘".format(str(Id)))
index=0
listName=[]
for each in response.xpath("//*[@id=‘list‘]/dl/dd"):
try:
src= each.xpath(".//a")[0].attrib[‘href‘]
title=each.xpath("string(.//a)")[0].root.strip()
if self.InTable(list,title):
print(title,"已经入库...")
elif title in listName:
print(title,"重复章节...")
else:
request= scrapy.Request(self.domainUrl+ src, callback = self.BookContent,dont_filter=False)
request.meta[‘id‘]=Id
request.meta[‘Chapter‘]=index
index=index+1
listName.append(title)
yield request
except Exception as e:
print("analysis item error:"+item["title"]+ e);
#爬取每个章节小说内容
def BookContent(self,response):
try:
item=BiqugespiderItem()
item[‘Title‘]=response.xpath("string(//*[@class=‘bookname‘]/h1)")[0].root.strip()
item[‘Content‘]=response.xpath("string(//*[@id=‘content‘])")[0].root.strip()
item[‘Id‘]= response.meta[‘id‘]
item[‘Chapter‘]= response.meta[‘Chapter‘]
yield item
except Exception as e:
print("login item error:"+item["title"]+ e);
#初始化数据库
def IniMysql(self):
#创建数据库
conn=pymysql.connect(host=self.host,port=self.port,user=self.user,password=self.password,database=‘mysql‘)
sql=‘create database if not exists Biquge‘
cursor=conn.cursor()
cursor.execute(sql)
cursor.close()
conn.close()
#创建表
conn=pymysql.connect(host=self.host,port=self.port,user=self.user,password=self.password,database=self.defaultDb)
cursor=conn.cursor()
sql= """CREATE TABLE IF NOT EXISTS BookBasic(
BookName varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘书名‘,
Author varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘作者‘,
Image longblob NULL COMMENT ‘书封面‘,
LatestChapter varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘最新章节‘,
Desc1 varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘内容描述‘,
Id char(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ‘主键‘,
PRIMARY KEY (`Id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
"""
cursor.execute(sql)
sql="""CREATE TABLE IF NOT EXISTS BookContent(
DId char(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
Title varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘详情标题‘,
Content longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT ‘内容信息‘,
Id char(36) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘书主键‘,
Chapter varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ‘章节‘,
SyncTime datetime(0) NULL DEFAULT NULL COMMENT ‘入库时间‘,
PRIMARY KEY (`DId`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
"""
cursor.execute(sql)
cursor.close()
conn.close()
if not resp:
# 获取小说信息
Id=uuid.uuid1()
#插入数据
self.mysql.ExecuteSql("insert into BookBasic (BookName,Author,Image,LatestChapter,Desc1,Id) values(%s,%s,%s,%s,%s,%s)",(str(BookName),str(Author),Image,str(LatestChapter),str(Desc1),str(Id)))
else:
Id=resp[0][0]
self.mysql.ExecuteSql("update BookBasic set LatestChapter=%s,Desc1=%s where Id=%s",(str(LatestChapter),str(Desc1),str(Id)))
class BiqugespiderPipeline(object):
def process_item(self, item, spider):
DId=uuid.uuid1()
SyncTime=datetime.datetime.now()
mysql=MySqlComment()
mysql.ExecuteSql("insert into BookContent values(%s,%s,%s,%s,%s,%s)",(str(DId),str(item[‘Title‘]),str(item[‘Content‘]),str(item[‘Id‘]),str(item[‘Chapter‘]),SyncTime))
return item
文章标题:scrapy+baiduapi搭建一个私人小说阅读器(智能爬取加智能朗读)(一)
文章链接:http://soscw.com/index.php/essay/43477.html