通过Jsoup刷取牛客网博客阅读量
通过Jsoup刷取牛客网博客阅读量
说明
好消息,牛客网博客上线了,对于像这种干净整洁没有广告的博客(csdn你看看人家),我们当然要在第一时间欢迎了,作者大一投入csdn的怀抱,后来又自己买服务器建个人博客,最后的最后终于牛客网也上线了自己的博客,当然要支持了(听说前一百名还有杯子送哦)。但是由于项目刚上线,自然会有很多bug,最重要的一个居然是不断刷新文章,阅读量会蹭蹭蹭的往上涨,这可不得了了,于是写了个简单的爬虫玩了玩,代码也就几十行。这里用到的编程语言是java,使用了jsoup这个库。
也许随着bug的修复,本篇文章的内容已经无效。
分析
首先导入jsoup的maven坐标
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.11.3</version> </dependency>
然后分析,大致分为两步,第一步获取所有的文章的URL,第二步骤,创建线程不断地请求url,ok,开始写代码。
获取文章url
通过观察牛客网博客首页发现,博客文章居然没有分页(现在发现好像每页显示10篇文章),那么就可以直接拿到所有文章的url了。看看url在哪里呢。
可以发现是在一个class为blog-list
的ul
标签中。每一个li
标签代表一篇文章。
li
标签内容如下:
链接地址就在li
标签下的href属性中。
现在开始写代码
List getAllArticleURLList(String blogUrl) throws IOException { Document doc = Jsoup.connect(blogUrl) .userAgent("Mozilla") .get(); Element element=doc.select("ul.blog-list").first(); Elements li=element.getElementsByTag("li"); List articleList=new LinkedList(); for (Element e:li){ Elements elements=e.getElementsByTag("a"); articleList.add(elements.first().attr("href")); } return articleList; }
这样我们就可以获取到所有的文章链接了(后来发现原来有分页的功能,想要拿到所有文章链接还需要做更多的工作,这里先不考虑了),运行结果如下:
创建线程处理
拿到了所有的文章链接,下面是通过get方法不断对链接进行请求,但是由于网络请求是一件很耗资源的事情,所以我们需要通过多个线程来处理文章,这里最大线程为20个来进行处理。
先写一个类来处理刷阅读量的任务
class DealThread implements Runnable{ int num; DealThread(int num){ this.num=num; } @Override public void run() { while (true){ //获取目前可以处理的url int index=getNowDealIndex(); //如果处理完了就退出 if (index>=list.size()){ return; } String url=list.get(index); //每个url刷num次 for (int i=0;i<num;i++){ try { Jsoup.connect(url).userAgent("Mozilla").get(); } catch (IOException e) { e.printStackTrace(); } } } } }
最后一步就是使用多线程线程来处理这些请求了,为了方便,本文就没有用到线程池了。
代码
package main; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Scanner; /** * @author zeng * @Classname NewCodeReader * @Description TODO * @Date 2019/7/28 15:35 */ public class NewCodeReader { private static final int THREAD_NUM=20; private static int nowDealIndex=-1; private static List<String> list; synchronized static int getNowDealIndex(){ nowDealIndex+=1; return nowDealIndex; } private static List<String> getAllArticleURLList(String blogUrl) throws IOException { Document doc = Jsoup.connect(blogUrl) .userAgent("Mozilla") .get(); Element element=doc.select("ul.blog-list").first(); Elements li=element.getElementsByTag("li"); List<String> articleList=new LinkedList<String>(); for (Element e:li){ Elements elements=e.getElementsByTag("a"); articleList.add("https://blog.nowcoder.net"+elements.first().attr("href")); } return articleList; } public static void main(String[] args) throws IOException, InterruptedException { String blogUrl=null; System.out.println("请输入刷取的数量:"); Scanner scanner=new Scanner(System.in); int num=scanner.nextInt(); System.out.println("请输入博客地址:"); if (scanner.hasNext()){ blogUrl=scanner.next(); } System.out.println("开始获取博客列表..."); list=getAllArticleURLList(blogUrl); System.out.println("共发现"+list.size()+"篇博客"); System.out.println("开始刷点击量..."); Thread[] threads=new Thread[THREAD_NUM]; for (int i=0;i<THREAD_NUM;i++){ Thread thread=new Thread(new DealThread(num)); thread.start(); threads[i]=thread; } for (Thread t:threads) { t.join(); } System.out.println("任务完成..."); } static class DealThread implements Runnable{ int num; DealThread(int num){ this.num=num; } @Override public void run() { while (true){ int index=getNowDealIndex(); if (index>=list.size()){ return; } String url=list.get(index); for (int i=0;i<num;i++){ try { Jsoup.connect(url).userAgent("Mozilla").get(); } catch (IOException e) { e.printStackTrace(); } } } } } }
最后
爬虫好玩,但是这是不道德的事情,看完本文大家可以尝试一下,但是也不要对牛客网后台服务器造成太大的压力。相信牛客官方很快就可以解决这个问题。