Makinami是为VirtualJudge程序中的主要子系统 Ayanami 提供微服务的爬虫子系统,采用RESTful设计,可以独立运行,也可以认为是一个独立完整的程序。既使得VJ主程序可以与爬虫模块分离,多地部署,也方便众OJ爱好者直接使用,不必再重复造轮子。
- flask
- scrapy
- mongodb
- 安装mongodb(省略)
- 安装依赖
pip install -r requirenments.txt
- 启动命令
python manage.py start
| OJ Name | OJ Code | Language |
|---|---|---|
| PKU JudgeOnline | poj | g++ gcc java pascal c++ c fortran |
oj_code参照上面OJ支持列表,参数传递使用json格式
URI: /<string:oj_code>/problem/<int:problem_id>
method: GET
URI /<string:oj_code>/problems
method: GET
URI: /<string:oj_code>/problem/<int:problem_id>
method: POST
| 参数名 | 说明 |
|---|---|
| username | 登录用户名 |
| password | 登录密码 |
| language | 语言类型(见OJ支持列表中的Language) |
| code | 提交的代码(需要已被base64加密) |
URI: /<string:oj_code>/status/<int:run_id>
method: GET
URI: /<string:oj_code>/user/<string:username>
method: POST
| 参数名 | 说明 |
|---|---|
| password | 登录密码 |
- 在config的ojs中添加对应的
oj_code - 在/app/api中添加对应的API文件,提供api规范的实现
- 在/app/illustrious/spiders添加对应的爬虫文件,实现:
- init爬虫: 爬取所有的题目
- problem爬虫: 根据 problemid 爬取单个题目
- submit爬虫: 提交代码并返回runid等信息
- result爬虫: 根据 runid 爬取运行结果
- user爬虫: 根据 username , password 爬取用户信息
参考样例文件:
- API文件:/app/api/poj.py
- 爬虫文件:/app/illustrious/spiders/poj.py
- 如果原OJ中增添的新题目怎么及时更新?
本来打算每日把原OJ所有的题目更新,但感觉做的无用功更多。因此init爬虫只在服务启动时使用,之后的新增题目和更新题目都采用“用后更新”的方式。
对于原OJ添加了新的题目。因为Makinami对于外部请求只会返回数据库中的信息,因此,对于数据库中没有的内容,将会返回 status: 404,然后运行爬虫尝试爬取,如果有新题目,就入库保存。
- 如果原OJ中题目有变动,怎么处理?
首先,在项目启动后,会立刻更新爬取所支持OJ的所有题目。在外部每次请求获得题目信息时,先将数据库中的题目信息返回,然后验证爬取时间,如果已经超过 7d 则新开辟进程,重新爬取该题目(用后爬取)。
- 如果提交题目后,运行结果未及时得出怎么处理?
爬虫会把未得到结果的runid开辟新进程,循环爬取,直到得到结果(持久化)或超时(30min),持久化后将保存在数据库中。 外部根据runid查询结果的请求,以数据库优先,如果数据库中不存在,则再将该runid开辟进程,循环爬取。
