开始的原因
女票爱看小说,最近沉迷一个小说论坛:91baby
每次都要打开浏览器进十分复古的网页里看
效果大概是这样的:
我觉得这样效果实在是有点差
就开始写一个小说网站给她用
基本思路
主要用爬虫获取原网站的小说数据
之后排版后显示在一个新的网页里
其实没有什么难度
主要想和大家分享一个开源项目:Toapi
项目主页里写了一句话:Every web site provides APIs.
数据部分 :Toapi
Toapi 是一个开源项目, 可以快速将一个网站的数据整理变成可调用的api接口,将数据最终以json的形式返回
地址:https://github.com/gaojiuli/toapi
下面我来展示一下简单的使用:
以91baby为例,我们需要解析小说的:
名字
内容
作者
链接
其实就是解析论坛的列表页、详情页
在Toapi的框架里
每项需要解析的数据都可以用一个item来表示
所以我们只需要定制好解析页面的规则
剩下的都可以交给框架来处理
解析列表页
class HotBook(Item):
# 需要解析的字段
__base_url__ = 'http://91baby.mama.cn'
title = XPath('//a[@class="xst"]/text()[1]')
author = XPath('//a[@class="xst"]/text()[1]')
url = XPath('//a[@class="xst"]/@href')
book_id = XPath('//a[@class="xst"]/@href')
# `clean__xxx`方法是用来进一步格式化信息用的
def clean_title(self, title):
if '《' in title:
return title[title.find('\u300a') + 1:title.find('\u300b')][:10]
else:
return '广告贴'
def clean_author(self, author):
if ':' in author:
return author[author.find(':') + 1:author.find('(')]
elif ':' in author:
return author[author.find(':') + 1:author.find('(')]
else:
return '广告贴'
def clean_book_id(self, book_id):
return book_id.split('-')[1]
class Meta:
source = XPath('//tbody[@class="thread_tbody"]')
# 定义路由 左边是我们内网的url,右边是源站的url
# 比如 我们访问 www.api.url/hotbook?page=1
# 框架就会向 www.xxx.com/form-171-1.html 发送请求
route = {'/hotbook?page=:page': '/forum-171-:page.html'}
解析书籍详情
class Book(Item):
__base_url__ = 'http://91baby.mama.cn'
title = XPath('//*[@id="wp"]/div[3]/text()[3]')
author = XPath('//*[@id="wp"]/div[3]/text()[3]')
total_page = XPath('//span[@class="pgt"]/div//a')
contents = XPath('//td[@class="t_f"]')
def clean_title(self, title):
return title.split('《')[1].split('》')[0]
def clean_author(self, author):
index = author.find('作者:') + 3
return author[index:]
def clean_contents(self, contents):
text = []
for item in contents:
content = strip(item.xpath('string(.)'))
if len(content) < 128:
text.append('全书完结!!! 以下的内容是网友书评!')
text.append(content)
return text
def clean_total_page(self, total_page):
try:
for index, page in enumerate(total_page):
num = page.xpath('./text()')[0]
if num == '下一页':
i = int(index) - 1
break
page = total_page[i].xpath('./text()')[0]
if '...' in page:
return int(page.replace('... ', ''))
return int(page)
except:
return 1
class Meta:
source = None
route = {'/book_id=:id?page=:page': '/thread-:id-:page-1.html'}
测试是否可以用
# Toapi 的入口
from toapi import Api
from items.hotbook import HotBook
from items.book import Book
from settings import MySettings
api = Api('', settings=MySettings)
api.register(HotBook)
api.register(Book)
if __name__ == '__main__':
api.serve()
# 运行程序
# python app.py
这下,当我们访问:http://127.0.0.1:5000/hotbook?page=1
就可以得到91baby论坛第一页书籍数据了
并且数据会json的形式返回,方便我们调用
{
"HotBook": [
{
"title": "\u5e7f\u544a\u8d34",
"author": "\u5e7f\u544a\u8d34",
"url": "http://91baby.mama.cn/thread-1502279-1-1.html",
"book_id": "1502279"
},
{
"title": "\u5e7f\u544a\u8d34",
"author": "\u5e7f\u544a\u8d34",
"url": "http://91baby.mama.cn/thread-1502414-1-1.html",
"book_id": "1502414"
},
}
用命令行展示的效果:
网页web部分
数据部分处理好了,剩下的就是web页面的搭建了
由于我是前端苦手,就网上找了一套别人开源写好的模板
效果大概是这样的:
配合追书神器的api还能显示其他分类的小说
阅读界面是这样的
进群:960410445 即可获取数十套PDF!
最后
由于没钱买域名 也没功夫去备案
网站就跑在腾讯云学生服务器上
由于上面还跑着其他很多测试程序
我就不把网站放出来给大家玩了
偷偷给我女票一个人用就行
网友评论