【React Native实战教程】GitHub Trending API数据的获取
2016-10-26 20:10
525 查看
项目开源地址:GitHub Popular,GitHubTrending
在源码中我发现了能够满足GitHub Popular的
冗余的数据太多,我们需要从这些冗余的数据中提取出
这些数据都是HTML格式的,而我们需要的是Json格式的数据。
接受一个url参数,如:https://github.com/trending/。
能够根据url参数返回对应的json或object数据。
为了实现这一需求,我们需要对请求url返回的数据进行解析,提取出我们所需要的数据,下面就跟大家分享GitHubTrending的具体实现:
数据模型
我们需要让GitHubTrending返回一个包含
从上面代码中可以看出,
将HTML解析成
我们通过
上面代码将HTML解析成一个包含
上述代码用于去除字符串中左右空格与换行。
上述代码接受一个url,然后通过
更多用例可参考:GitHubPopular:DataRepository.js
现在已经满足了GitHub Popular项目的需求,而且稳定性还是不错的,感兴趣的小伙伴可以下载GitHub Popular
体验一下。
如果喜欢我的文章,那就关注我的博客@ devio.org吧,让我们一起做朋友~~
个人博客:干货文章都在这里哦
GitHub:我的开源项目
关于GitHub Trending API的困惑
GitHub Popular中有个treding模块,该模块是GitHub的treding的手机版,在这个模块中你可以使用只有在PC上才能使用的功能。为了开发这个
treding模块我们需要获取GitHub的treding的API数据。不过不幸的的是GitHub并没有开放有关trending的API,所以想调GitHub的treding的API已经是不现实的了。
拨开云雾见月明
为了给GitHub Popular的treding模块提供可靠的数据支持,我查遍了所有看似可行的方法,但都没能达到要求。本着
只要思想不滑坡,方法总比问题多态度,我打开了https://github.com/trending的页面源码研究了起来。
在源码中我发现了能够满足GitHub Popular的
treding模块的所有数据,但存在如下两个问题:
冗余的数据太多,我们需要从这些冗余的数据中提取出
treding模块真正需要的数据。
这些数据都是HTML格式的,而我们需要的是Json格式的数据。
GitHubTrending项目的开发
经过上述的分析,我们的需求与任务也逐渐明确了,我们需要一个能为我们提供可靠的https://github.com/trending数据的模块,暂且叫它GitHubTrending吧。这个模块需要满足如下需求:接受一个url参数,如:https://github.com/trending/。
能够根据url参数返回对应的json或object数据。
为了实现这一需求,我们需要对请求url返回的数据进行解析,提取出我们所需要的数据,下面就跟大家分享GitHubTrending的具体实现:
数据模型TrendingRepoModel
我们需要让GitHubTrending返回一个包含TrendingRepoModel.js的集合,
TrendingRepoModel.js的代码如下:
/** * TrendingRepoModel * 项目地址:https://github.com/crazycodeboy/GitHubTrending * 博客地址:http://www.devio.org * @flow */ export default class TrendingRepoModel { constructor(fullName,url,description,language,meta,contributors,contributorsUrl) { this.fullName = fullName; this.url = url; this.description = description; this.language = language; this.meta = meta; this.contributors = contributors; this.contributorsUrl = contributorsUrl; } }
从上面代码中可以看出,
TrendingRepoModel.js包含了https://github.com/trending/的所以数据的模型。
将HTML解析成TrendingRepoModel
我们通过TrendingUtil.js将HTML解析成包含
TrendingRepoModel.js的集合。下面是
TrendingUtil.js文件代码:
/** * TrendingUtil * 工具类:用于将github trending html 转换成 TrendingRepoModel * 项目地址:https://github.com/crazycodeboy/GitHubTrending * 博客地址:http://www.devio.org * @flow */ import TrendingRepoModel from './TrendingRepoModel'; import StringUtil from './StringUtil'; export default class TrendingUtil { static htmlToRepo(responseData) { responseData = responseData.substring(responseData.indexOf('<li class="repo-list-item'), responseData.indexOf('</ol>')).replace(/\n/, ''); var repos = []; var splitWithH3 = responseData.split('<h3'); splitWithH3.shift(); for (var i = 0; i < splitWithH3.length; i++) { var repo = new TrendingRepoModel(); var html = splitWithH3[i]; this.parseRepoBaseInfo(repo, html); var metaNoteContent = this.parseContentOfNode(html, 'repo-list-meta'); this.parseRepoMeta(repo, metaNoteContent); this.parseRepoContributors(repo, metaNoteContent); repos.push(repo); } return repos; } static parseContentOfNode(htmlStr, classFlag) { var noteEnd = htmlStr.indexOf(' class="' + classFlag); var noteStart = htmlStr.lastIndexOf('<', noteEnd) + 1; var note = htmlStr.substring(noteStart, noteEnd); var sliceStart = htmlStr.indexOf(classFlag) + classFlag.length + 2; var sliceEnd = htmlStr.indexOf('</' + note + '>', sliceStart); var content = htmlStr.substring(sliceStart, sliceEnd); return StringUtil.trim(content); } static parseRepoBaseInfo(repo, htmlBaseInfo) { var urlIndex = htmlBaseInfo.indexOf('<a href="') + '<a href="'.length; var url = htmlBaseInfo.slice(urlIndex, htmlBaseInfo.indexOf('">', urlIndex)); repo.url = url; repo.fullName = url.slice(1, url.length); var description = this.parseContentOfNode(htmlBaseInfo, 'repo-list-description'); var index = description.indexOf('</g-emoji>'); if (index !== -1) { var indexEmoji = description.indexOf('</g-emoji>'); var emoji = description.substring(description.indexOf('>') + 1, indexEmoji) description = emoji + description.substring(indexEmoji + '</g-emoji>'.length); } repo.description = description; } static parseRepoMeta(repo, htmlMeta) { var splitWit_n = htmlMeta.split('\n'); if (splitWit_n[0].search('stars') === -1) { repo.language = splitWit_n[0]; } for (var i = 0; i < splitWit_n.length; i++) { if (splitWit_n[i].search('stars') !== -1) { repo.meta = StringUtil.trim(splitWit_n[i]); break; } } } static parseRepoContributors(repo, htmlContributors) { var splitWitSemicolon = htmlContributors.split('"'); repo.contributorsUrl = splitWitSemicolon[1]; var contributors = []; for (var i = 0; i < splitWitSemicolon.length; i++) { var url = splitWitSemicolon[i]; if (url.search('http') !== -1) { contributors.push(url); } } repo.contributors = contributors; } }
上面代码将HTML解析成一个包含
TrendingRepoModel.js的集合,为了去除空行,上述代码中用到了
StringUtil.js工具类:
/** * 字符串工具类 * 项目地址:https://github.com/crazycodeboy/GitHubTrending * 博客地址:http://www.devio.org * @flow */ export default class StringUtil { /* * 去掉字符串左右空格、换行 */ static trim( text ){ if (typeof(text) == "string") { return text.replace(/^\s*|\s*$/g, ""); } else{ return text; } } }
上述代码用于去除字符串中左右空格与换行。
GitHubTrending封装
经过上述步骤之后,我们的准备工作已经完成了,下面我们就可以通过GitHubTrending来提供数据了:
/** * 从https://github.com/trending获取数据 * 项目地址:https://github.com/crazycodeboy/GitHubTrending * 博客地址:http://www.devio.org * @flow */ import TrendingUtil from './TrendingUtil'; export default class GitHubTrending { GitHubTrending(){//Singleton pattern if (typeof GitHubTrending.instance==='object') { return GitHubTrending.instance; } GitHubTrending.instance=this; } fetchTrending(url){ return new Promise((resolve,reject)=>{ fetch(url) .then((response)=>response.text()) .catch((error)=>{ reject(error); console.log(error); }).then((responseData)=>{ try { resolve(TrendingUtil.htmlToRepo(responseData)); } catch (e) { reject(e); } }).done(); }); } }
上述代码接受一个url,然后通过
fetchAPI获取url返回的HTML数据,最后将HTML解析成包含
TrendingRepoModel.js的集合。
如何使用GitHubTrending
为了方面大家使用,我已将GitHubTrending发布到npm,大家可以通过下列步骤来使用GitHubTrending。安装
打开在终端中运行如下命名进行安装:npm i GitHubTrending --save
使用
new GitHubTrending().fetchTrending(url) .then((data)=> { // }).catch((error)=> { // });
更多用例可参考:GitHubPopular:DataRepository.js
总结
从探索使用官方API,到自己动手去实现它,虽然过程比较曲折,但最终还是完成目标。经过反复测试GitHubTrending现在已经满足了GitHub Popular项目的需求,而且稳定性还是不错的,感兴趣的小伙伴可以下载GitHub Popular
体验一下。
最后
既然来了,留下个喜欢再走吧,鼓励我继续创作(^_^)∠※如果喜欢我的文章,那就关注我的博客@ devio.org吧,让我们一起做朋友~~
戳这里,加关注哦:
微博:第一时间获取推送个人博客:干货文章都在这里哦
GitHub:我的开源项目
相关文章推荐
- 小白学react之restful api获取服务器数据实战
- 【稀饭】react native 实战系列教程之影片数据获取并解析
- Python开发实战教程(8)-向网页提交获取数据
- 程序员教你通过获取api爬取新浪微博内容数据实战
- react项目实战(权限模块开发七)通过ajax技术获取数据
- 【备忘】2017年最新React开发Native开发安卓与ios平台的GitHub App视频教程
- react-native 项目实战 -- 新闻客户端(5) -- 完善首页列表数据
- React Native实战项目企业通信录(含视频教程)-环境搭建
- [教程] React Native基础实战(1)—— 制作一个简单的按钮
- React Native iOS原生模块开发实战|教程|心得|如何创建React Native iOS原生模块
- React-Native 自定义Button 获取远程数据
- 用TypeScipt和AMD模块化理念实现React官方教程(四)获取数据
- React Native Android原生模块开发实战|教程|心得|如何创建React Native Android原生模块
- React-Native 之 GD (十二)海淘半小时热门 及 获取最新数据个数功能 (角标)
- [教程] ListView的使用和封装——实战React Native中级案例01
- react_native 项目实战 (4) 自定义分类 使用 CheckBox 以及 数据存储asyncStorage
- react-native 项目实战 -- 新闻客户端(4) -- 请求网络数据
- ReactNative学习实例(三) 使用fetch获取网络数据
- react native 实战系列教程之热更新原理分析与实现