Python中如何使用Toapi让任何一个网站提供API接口

Github: https://github.com/gaojiuli/toapi

Toapi

这个项目的意义在于让一个没有提供 API 的网站拥有 API 接口。

安装

使用

from pprint import pprint

from toapi import XPath, Item, Api

api = Api(‘https://news.ycombinator.com/’)

class Post(Item): url = XPath(’//a[@class=“storylink”][1]/@href’) title = XPath(’//a[@class=“storylink”][1]/text()’)

class Meta:
    source = XPath('//tr[@class="athing"]')
    route = '/'

api.register(Post)

pprint(api.parse(’/’))

api.serve()

然后你就让一个网站提供了 api 服务。 那些没有 api 的网站,就让我们自己给他们弄上 api 接口!

Github: https://github.com/gaojiuli/toapi


Python中如何使用Toapi让任何一个网站提供API接口

44 回复

很好玩 一只只的小爬虫么


Toapi是一个用来把网站内容快速封装成API的Python库,它通过解析HTML来提取结构化数据。不过需要提醒你,这个项目在GitHub上已经几年没更新了,而且依赖的解析库可能和现在的一些网站结构不太兼容。如果你要处理现代JavaScript渲染的网站,它可能不太行。

不过,它的核心思路还是挺清楚的,我写个简单的例子给你看看。假设我们要从一个博客列表页抓取文章标题和链接。

首先,安装(虽然可能遇到依赖问题):

pip install toapi

然后写代码:

from toapi import Css, Item, Api

# 1. 定义你要的数据结构
class Post(Item):
    title = Css('h2 a')  # 用CSS选择器定位标题
    link = Css('h2 a', attr='href')  # 提取href属性

    class Meta:
        source = Css('.post')  # 每篇文章的容器
        route = '/'  # 路由,这里用根路径

# 2. 创建API实例并设置源网站
api = Api('https://example-blog.com')  # 换成目标网站

# 3. 注册这个数据项
api.register(Post)

# 4. 运行服务(默认端口5000)
if __name__ == '__main__':
    api.run()

运行这个脚本,访问 http://localhost:5000/ 就能拿到JSON格式的文章列表了。Toapi的核心就是定义Item类,用Css选择器告诉它去哪里找数据。

但说实话,现在更靠谱的做法是自己用requests+BeautifulSoupScrapy来写,或者用Playwright这类工具处理动态页面。Toapi的想法不错,但维护状态不太理想,用在正式项目里要小心。

总结:可以用但别太依赖,了解思路就行。

想法不错,赞

和爬虫有点像,只不过不爬数据,做中间转发的感觉

有点意思, 任何网站?

yahoo 有个 yql…

浏览器能访问的网站就行,原理就是把 html 按照一定规则转为 json。

酷,我就打算做这种感觉的东西。又孤陋寡闻了。Yahoo 这个能在本地部署不

idea 点赞!快速看了下代码,这个玩意如何处理 ajax 请求得到的数据?还有,requests 的请求头,user-agent 要怎么写也是个蛋疼的问题。。。。。。

有木有其他版本?

ajax 用 selenium 处理,这个已经在本地分支写好了。头部这些都能自定义。

你指的是?

酷! Star,有机会研究下

羡慕有想法又有行动力的大佬

Star,想法挺有意思的

有一个问题没有解决,就是 XPath 选择出来的结果是一个 list, 但是期望的是一个字符串.

这种写法不错

api 格式可以自定义吗?

抱歉 ,刚看到,我没用 xpath 不过我发现 cssselector 也有这个问题 我已经解决了并提交 pr,我还提交了一些参数的优化 比如 requests 的 get 支持 headers,flask 的一些 options 参数传递问题,新增加了一个用 css 提取写的豆瓣 demo
![]( http://oe7yjec8x.bkt.clouddn.com/howie/2017-12-04-00.png-blog.howie)

关于 xpath 的解决方式,我另一个项目和你这个项目的目标值提取方式很像,我当时的解决方式是让使用者自己定义一个函数在 Item 的继承类里面,比如
python<br>from talonspider import Item, TextField, AttrField<br>from pprint import pprint<br><br>try:<br> bool(type(unicode))<br>except NameError:<br> unicode = str<br><br><br>class DoubanItem(Item):<br> target_item = TextField(css_select='div.item')<br> title = TextField(css_select='span.title')<br> cover = AttrField(css_select='div.pic&gt;a&gt;img', attr='src')<br> abstract = TextField(css_select='span.inq')<br><br> def tal_title(self, title):<br> # 这里当返回是 list,让使用者在自己定义的这个函数里解决<br> if isinstance(title, unicode):<br> return title<br> else:<br> return ''.join([i.text.strip().replace(u'\xa0', '') for i in title])<br>
项目地址 https://github.com/howie6879/talonspider

如果你觉得可以 我们可以改成这样子去解决

requirement.txt 里少了 requests 提了一个 pr

这个运行起来怎么调用 api, 小白求指点。 比如就是这个例子里面的代码。

挺有意思的

这个作为数据提供,你可以自己写 API 服务,然后包装一下这个数据。

直接访问网址就可以了,内置服务器是 flask

这个项目和我的思路差不多。可惜不开源

可以进一步做成 ifttt

有没有具体的用法啊,感觉玩不转呢。

php node。

赞,以前就想实现了,可惜行动力不足,只做了几个特定网站的支持就烂尾了

暂时只有几个案例在 example 目录下面。文档会和 1.0 版一起发布。

暂时没有哦,期待有兴趣朋友实现一下。


我看这个就是一个爬虫的效果, 这个 api 在哪里调用?

![20171204145519]( http://7xpvdr.com1.z0.glb.clouddn.com/1204145459.png)

能不能返回多级信息?举个例子:你那

不小心点到 enter。。。
你那个电影的例子,返回的是标题的和链接,而想要的是标题和链接里的下载地址

已 start~~~

直接运行就行了,访问本地的网址 127.0.0.1:5000/,内置的 flask,可以有 flask 功能。路由通过 Meta.route 配置

可以呀,下一层配置新的 item 就行了,匹配下一层的路由

没访问几次就被 ban 了

+1

你这个没什么卵用。当服务用的话就是个爬虫 /反向代理,访问量大了指定被 ban,买代理的话成本又高。
本地用的话自己想怎么爬怎么爬,两分钟搞定的事情不需要用这个。

最后:没什么卵用😒

如何处理 js ?



1. 同一个 url 只访问一次, 缓存系统
2. 和通常爬虫相比最大的优势是自动实时更新

这个库用的是 selenium 加载异步页面

回到顶部