Python中如何使用Toapi2.0优雅地让网站提供API接口?
Toapi
简介
Toapi 是一个能够将任何 web 网站转化为 api 服务的库。当前版本为 2.0 版,完全重新设计了用法,使得代码更加优雅,更加 pythonic。
Get Started
Installation
$ pip install toapi
$ toapi -v
toapi, version 2.0.0
用法
创建 app.py ,复制下面的代码:
from flask import request
from htmlparsing import Attr, Text
from toapi import Api, Item
api = Api()
@api.site(‘https://news.ycombinator.com’)
@api.list(’.athing’)
@api.route(’/posts?page={page}’, ‘/news?p={page}’)
@api.route(’/posts’, ‘/news?p=1’)
class Post(Item):
url = Attr(’.storylink’, ‘href’)
title = Text(’.storylink’)
@api.site(‘https://news.ycombinator.com’)
@api.route(’/posts?page={page}’, ‘/news?p={page}’)
@api.route(’/posts’, ‘/news?p=1’)
class Page(Item):
next_page = Attr(’.morelink’, ‘href’)
api.run(debug=True, host=‘0.0.0.0’, port=5000)
运行 python app.py
打开浏览器访问 http://127.0.0.1:5000/posts?page=1
你讲获得类似下面的结果:
{
"Page": {
"next_page": "http://127.0.0.1:5000/posts?page=2"
},
"Post": [
{
"title": "Mathematicians Crack the Cursed Curve",
"url": "https://www.quantamagazine.org/mathematicians-crack-the-cursed-curve-20171207/"
},
{
"title": "Stuffing a Tesla Drivetrain into a 1981 Honda Accord",
"url": "https://jalopnik.com/this-glorious-madman-stuffed-a-p85-tesla-drivetrain-int-1823461909"
}
]
}
直接看上面的案例就能很容易理解用法. 目前版本完全开源。
Python中如何使用Toapi2.0优雅地让网站提供API接口?
要优雅地用Toapi 2.0给网站提供API,核心是理解它的“管道”机制。Toapi 2.0通过定义Item来结构化数据,并用Pipeline处理这些数据。下面是一个抓取名言网站(quotes.toscrape.com)并暴露为API的完整示例:
from toapi import XPath, Item, Api
from toapi.settings import Settings
# 1. 定义你的数据模型(Item)
class Quote(Item):
# 使用XPath选择器定位元素
text = XPath('//span[@class="text"]/text()')
author = XPath('//small[@class="author"]/text()')
tags = XPath('//div[@class="tags"]/a[@class="tag"]/text()')
class Meta:
# 指定从哪个URL抓取数据
source = XPath('//div[@class="quote"]')
# 指定API的访问路径
route = '/quotes'
# 2. 可选:自定义设置
class MySettings(Settings):
# 开启缓存避免频繁请求
cache = {
'type': 'memory',
'expire': 600 # 10分钟
}
# 设置请求间隔,避免给目标网站造成压力
web = {
'request_delay': 2
}
# 3. 创建API实例并注册Item
api = Api('https://quotes.toscrape.com', settings=MySettings)
api.register(Quote)
# 4. 运行服务器(默认端口5000)
if __name__ == '__main__':
api.run()
运行后访问 http://localhost:5000/quotes 就能获取JSON格式的名言数据。关键点在于:
- Item定义:用XPath精准定位需要的数据字段
- 路由配置:
route参数决定了API的访问路径 - 设置优化:通过缓存和请求延迟来平衡效率和友好性
更优雅的做法是添加分页支持。修改Quote类的Meta配置:
class Quote(Item):
# ... 字段定义同上 ...
class Meta:
source = XPath('//div[@class="quote"]')
route = '/quotes'
# 添加分页支持
route = {
'/quotes': '获取所有名言',
'/quotes?page=:page': '分页获取'
}
这样就能通过 /quotes?page=2 访问第二页数据。
总结:定义好Item和路由是关键。

