作者 | bisal
责编 | 张红月
技术解析来自bisal的个人杂货铺,博客之星6号博主
快过年了,有人欢喜有人忧。喜的是放假了,忧的是又要被(找)相(对)亲(象)。程序员们,Are you ready?
来来来,放松一下!
如今人人都是自媒体,通过写博客、分享学习笔记聚集粉丝已是很多人屡试不爽的方法。作为日PV过千万,仅次于Github的程序员社区,CSDN博客原创文章发布量平均为7300篇/天,同比2017年,每天新增了2000多篇文章。在这些数字的背后,是那些长年在键盘后面辛勤努力的技术英雄们,他们笔耕不辍、乐于分享,布道知识,共同精进。
分享知识的同时,还获得大量粉丝关注,例如知名的CSDN博主任玉刚、刘望舒等。同时,CSDN社区为感谢辛勤创作的博主们,还举办了博客之星活动。
肉眼数名次,你晕了吗?程序员Say No!
乍一看,这个页面很清晰,但有个问题,就是无法知道每个人的排名,只能肉眼数名次。
作为程序员,是不能容忍耗费体力的事,因此需要考虑,如何自动排名。
既然是网页,就存在解析内容的可能,看了下网页源码,都是普通的HTML标签,如下所示,因此,可以通过技术的手段,解析网页:
<div class="item" id="006">
<div class="user-info">
<div class="user-id">006</div>
<div class="avatar">
< a href=" " target="_blank">< img src="https://profile.csdnimg.cn/8/4/6/1_bisal" alt="bisal"></ a>
</div>
<div class="expert-flag" >
<svg class="icon">
<use xlink:href="#expert"></use>
</svg>
</div>
<div class="user-name"><span class="oneline">bisal</span></div>
<div class="article-num">
<span>原创博文:354<br>
</span>
</div>
<div class="user-number"><span>当前票数:<em id="vote_num_2731">337</em></span></div>
</div>
<div class="user-button">
<div class="vote" onclick="click_vote(2731,337);">
<span>投票</span>
</div>
<div data-track-click='{"mod":"737","con":",,"}' class="pull"><span>为TA拉票</span></div>
</div>
</div>
程序员助力老婆项目分析
网页解析,有很多开源的工具可用,我的本硕毕设,做的就是专利网页抓取解析,而且曾经帮老婆的一个项目,抓取、解析过当当网这些电商网站,用的就是神器-Jsoup,可谓屡试不爽。
Jsoup是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。他提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。Jsoup是基于MIT协议发布的,可放心使用于商业项目。
他的主要功能,包括如下这些:
1. 从一个URL,文件或字符串中解析HTML;
2. 使用DOM或CSS选择器来查找、取出数据;
3. 可操作HTML元素、属性、文本;
Jsoup的官网是https://jsoup.org/
排名分析
首先,明确下,需要从网页中,解析到的内容,包括编号、博主名称、原创博文数量、票数:
Document doc = Jsoup.parse(url, Constants.TIME_OUT);
Elements elements = doc.getElementsByClass("user-info");
List<Blogger> list = new ArrayList<Blogger>();
for (Element element : elements) {
if (!element.text().trim().equals("")) {
Blogger blogger = new Blogger();
blogger = getBlogger(element.text());
list.add(blogger);
}
}
定义一个实体类Blogger,包含了编号、博主名称、原创博文数量、票数。
private String no;
private String name;
private String articleNo;
private int tickerNo;
从网页中看,每个博主信息,都在<div class="user-info>标签内,首先实例化Document对象,使用getElementsByClass()方法,定位class是user-info的标签,由于需要循环处理所有博主,因此使用List,成员类型是Blogger,element.text()就是从<div class="user-info>解析出的各部分内容,注意此处需要判断是否为空,因为要得出编号、博主名称、原创博文数量、票数这些信息,所以还要对内容,进行字符串分割,此处自定义getBlogger()方法,用于拆解字符串。
Document doc = Jsoup.parse(url, Constants.TIME_OUT);
Elements elements = doc.getElementsByClass("user-info");
List<Blogger> list = new ArrayList<Blogger>();
for (Element element : elements) {
if (!element.text().trim().equals("")) {
Blogger blogger = new Blogger();
blogger = getBlogger(element.text());
list.add(blogger);
}
}
getBlogger()方法,会根据element.text()的返回值,做字符串分割,再存储进Blogger对象。
Blogger blogger = new Blogger();
String no = line.substring(0, line.indexOf(" "));
String name = line.substring(line.indexOf(" ") + 1, line.indexOf(" 原创"));
String articleNo = line.substring(line.indexOf(":") + 1, line.indexOf("当前") - 1);
int ticketNo = Integer.valueOf(line.substring(line.indexOf("当前票数:") + 5, line.length()));
blogger.setNo(no);
blogger.setName(name);
blogger.setArticleNo(articleNo);
blogger.setTicketNo(ticketNo);
return blogger;
得到了编号、博主名称、原创博文数量、票数,现在需要做的,就是排序,准确地说,是用票数排序,由于是整型,因此只要按照>、=、<,即可完成排序。
Collections.sort(list, new Comparator<Blogger>(){
/*
* int compare(Person p1, Person p2) 返回一个基本类型的整型,
* 返回负数表示:p1大于p2,
* 返回0 表示:p1和p2相等,
* 返回正数表示:p1小于p2
*/
public int compare(Blogger p1, Blogger p2) {
//按照Person的年龄进行升序排列
if(p1.getTicketNo() < p2.getTicketNo()){
return 1;
}
if(p1.getTicketNo() == p2.getTicketNo()){
return 0;
}
return -1;
}
});
将List成员打印出来。
int i = 1;
for (Blogger blogger : list) {
System.out.println(i + " " + blogger.getName() + " " + blogger.getTicketNo());
i++;
}
此时,就是按照票数,进行的展示:
写文章赢大奖
知道你们想问奖品好久了,开年会的时候,大家首先会问奖品有什么?博客之星活动也不例外,奖品超酷炫:
投票有机会赢超跑免费驾驶
本次王子出行(王子车库科技有限公司)
秉承“让租车比买车更划算!”的商业理念,专注于为广大出行需求用户提供高端车型订制出行服务;
如何参与投票
点击阅读原文或者扫描下方海报二维码即可参与投票,赢取开超跑机会。
print_r('点个好看吧!');
var_dump('点个好看吧!');
NSLog(@"点个好看吧!");
System.out.println("点个好看吧!");
console.log("点个好看吧!");
print("点个好看吧!");
printf("点个好看吧!");
cout << "点个好看吧!" << endl;
Console.WriteLine("点个好看吧!");
fmt.Println("点个好看吧!");
Response.Write("点个好看吧!");
alert("点个好看吧!")
echo "点个好看吧!"