http编程系列(二)——java爬虫实现刷个人博客的访问量
来源:互联网 发布:java web 高并发 编辑:程序博客网 时间:2024/06/08 08:35
实现功能
这里实现的功能是一个根据个人博客主页,搜索出所有的个人博文链接,然后一个一个去访问,从而增加访问量。这里我发现一个问题,csdn既没有做接口ip访问量的限制,访问量统计时也没有做同一ip相同时间段的重复访问重复计数的处理。这也时这个程序能够刷访问量的原因。
思路
进入个人博客主页,如我的博客:”http://blog.csdn.net/luo4105”,它会出来一个博客的列表(blogListPage),但是,它没有显示所有的博客,而是分页显示,这里我们就找到下一页
的链接并访问它,然后如此递归,直到尾页为止。这样我们就获得了所有的分页博客的地址。然后访问所有的分页博客,拿到它们的页面数据,找出所有的博客链接,访问。
这里工作就分为以下几步
1.根据个人主页url,访问个人主页并拿到页面数据
2.找出下一页的URL并访问,重复该动作直到没有下一页,将每个url都存到set集合中
3.遍历set集合,访问所有的博客列表页面,获得页面数据,找到页面数据中所有的博客链接,存入博客链接的set集合
4.遍历博客链接的set集合,访问所有博客链接
具体实现步骤
1.根据个人主页url,访问个人主页并拿到页面数据
访问url,并拿到响应的代码如下,为了重复使用,我将其放入工具类中。
访问URL并拿到响应代码
public class HttpUtil { public static InputStream doGet(String urlstr) throws IOException { URL url= new URL(urlstr); HttpURLConnection conn= (HttpURLConnection) url.openConnection(); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"); InputStream inputStream= conn.getInputStream(); return inputStream; }}将响应的InputStream转成String的代码
public class StreamUtil { public static String inputStreamToString(InputStream is, String charset) throws IOException { byte[] bytes = new byte[1024]; int byteLength = 0; StringBuffer sb = new StringBuffer(); while((byteLength = is.read(bytes)) != -1) { sb.append(new String(bytes, 0, byteLength, charset)); } return sb.toString(); } }
综合使用就是
public void addBlogListPageUrl(String pageUrl, Set<String> pagelistUrls) throws IOException {InputStream is = HttpUtil.doGet(pageUrl);String pageStr = StreamUtil.inputStreamToString(is, "UTF-8");is.close();System.out.println(pageStr);}这里后台输出页面的代码。
2.找出下一页的URL并访问,重复该动作直到没有下一页,将每个url都存到set集合中
开启f12,我们来看下一页是怎么样的。
这里我们可以通过下面的正则匹配<a href=”xxxxxx”>下一页</a>标签
private String nextPagePanner = "<a href=\"/luo4105/article/list/[0-9]{1,10}\">下一页</a>";//下一页的正则表达式然后我们用正则匹配URL链接
private String nextPageUrlPanner = "/luo4105/article/list/[0-9]{1,10}";//下一页Url的正则表达式加上匹配正则,功能代码如下
private String csdnBlogUrl = "http://blog.csdn.net/";private String nextPagePanner = "<a href=\"/luo4105/article/list/[0-9]{1,10}\">下一页</a>";//下一页的正则表达式private String nextPageUrlPanner = "/luo4105/article/list/[0-9]{1,10}";//下一页Url的正则表达式/** * 通过下一页,遍历所有博客目录页面链接 * @param pageUrl * @param pagelistUrls * @throws IOException */public void addBlogListPageUrl(String pageUrl, Set<String> pagelistUrls) throws IOException {InputStream is = HttpUtil.doGet(pageUrl);String pageStr = StreamUtil.inputStreamToString(is, "UTF-8");is.close();Pattern nextPagePattern = Pattern.compile(nextPagePanner);Matcher nextPagematcher = nextPagePattern.matcher(pageStr);if (nextPagematcher.find()) {nextPagePattern = Pattern.compile(nextPageUrlPanner);nextPagematcher = nextPagePattern.matcher(nextPagematcher.group(0));if (nextPagematcher.find()) {pagelistUrls.add(csdnBlogUrl + nextPagematcher.group(0));System.out.println("成功添加博客列表页面地址:" + csdnBlogUrl + nextPagematcher.group(0));//addBlogListPageUrl(csdnBlogUrl + nextPagematcher.group(0), pagelistUrls);这是调用添加blog链接的方法}}}
3.遍历set集合,访问所有的博客列表页面,获得页面数据,找到页面数据中所有的博客链接,存入博客链接的set集合
我们先看看再blog列表页面中的blog链接
匹配/luo4105/art......的正则如下
private String artlUrl = "/luo4105/article/details/[0-9]{8,8}";//博客utl的正则表达式功能代码
private String artlUrl = "/luo4105/article/details/[0-9]{8,8}";//博客utl的正则表达式/** * 添加搜索博客目录的博客链接 * @param blogListURL 博客目录地址 * @param artlUrls 存放博客访问地址的集合 * @throws IOException */public void addBlogUrl(String blogListURL, Set<String> artlUrls) throws IOException {InputStream is = HttpUtil.doGet(blogListURL);String pageStr = StreamUtil.inputStreamToString(is, "UTF-8");is.close();Pattern pattern = Pattern.compile(artlUrl);Matcher matcher = pattern.matcher(pageStr);while (matcher.find()) {String e = matcher.group(0);System.out.println("成功添加博客地址:" + e);artlUrls.add(e);}}4.遍历博客链接的set集合,访问所有博客链接
代码如下
@Testpublic void visitBlog() throws IOException {addBlogUrl();/** 这里可以写循环 **/for(String blogUrl : blogUrls) {String artlUrl = csdnBlogUrl + blogUrl;InputStream is = HttpUtil.doGet(artlUrl);if (is != null) {System.out.println(artlUrl + "访问成功");}is.close();} /** 这里可以写循环 **/ }贴出所有代码
访问URL并拿到响应工具类
public class HttpUtil { public static InputStream doGet(String urlstr) throws IOException { URL url= new URL(urlstr); HttpURLConnection conn= (HttpURLConnection) url.openConnection(); conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"); InputStream inputStream= conn.getInputStream(); return inputStream; }}将响应的InputStream转成String的工具类
public class StreamUtil { public static String inputStreamToString(InputStream is, String charset) throws IOException { byte[] bytes = new byte[1024]; int byteLength = 0; StringBuffer sb = new StringBuffer(); while((byteLength = is.read(bytes)) != -1) { sb.append(new String(bytes, 0, byteLength, charset)); } return sb.toString(); } }blog刷访问类
/** * @author 逝夕诚 * 刷csdn博客访问量 */public class AddCsdnBlogPV {private String csdnBlogUrl = "http://blog.csdn.net/";private String firstBlogListPageUrl = "http://blog.csdn.net/luo4105";//博客主页private String nextPagePanner = "<a href=\"/luo4105/article/list/[0-9]{1,10}\">下一页</a>";//下一页的正则表达式private String nextPageUrlPanner = "/luo4105/article/list/[0-9]{1,10}";//下一页Url的正则表达式private String artlUrl = "/luo4105/article/details/[0-9]{8,8}";//博客utl的正则表达式private Set<String> blogListPageUrls = new TreeSet<>();private Set<String> blogUrls = new TreeSet<>();@Testpublic void visitBlog() throws IOException {addBlogUrl();for(String blogUrl : blogUrls) {String artlUrl = csdnBlogUrl + blogUrl;InputStream is = HttpUtil.doGet(artlUrl);if (is != null) {System.out.println(artlUrl + "访问成功");}is.close();}}/** * @throws IOException * 加载所有的bolg地址 */@Testpublic void addBlogUrl() throws IOException {blogListPageUrls.add(firstBlogListPageUrl);addBlogListPageUrl(firstBlogListPageUrl, blogListPageUrls);for (String bolgListUrl : blogListPageUrls) {addBlogUrl(bolgListUrl, blogUrls);}}/** * 通过下一页,遍历所有博客目录页面链接 * @param pageUrl * @param pagelistUrls * @throws IOException */public void addBlogListPageUrl(String pageUrl, Set<String> pagelistUrls) throws IOException {InputStream is = HttpUtil.doGet(pageUrl);String pageStr = StreamUtil.inputStreamToString(is, "UTF-8");is.close();Pattern nextPagePattern = Pattern.compile(nextPagePanner);Matcher nextPagematcher = nextPagePattern.matcher(pageStr);if (nextPagematcher.find()) {nextPagePattern = Pattern.compile(nextPageUrlPanner);nextPagematcher = nextPagePattern.matcher(nextPagematcher.group(0));if (nextPagematcher.find()) {pagelistUrls.add(csdnBlogUrl + nextPagematcher.group(0));System.out.println("成功添加博客列表页面地址:" + csdnBlogUrl + nextPagematcher.group(0));addBlogListPageUrl(csdnBlogUrl + nextPagematcher.group(0), pagelistUrls);}}}/** * 添加搜索博客目录的博客链接 * @param blogListURL 博客目录地址 * @param artlUrls 存放博客访问地址的集合 * @throws IOException */public void addBlogUrl(String blogListURL, Set<String> artlUrls) throws IOException {InputStream is = HttpUtil.doGet(blogListURL);String pageStr = StreamUtil.inputStreamToString(is, "UTF-8");is.close();Pattern pattern = Pattern.compile(artlUrl);Matcher matcher = pattern.matcher(pageStr);while (matcher.find()) {String e = matcher.group(0);System.out.println("成功添加博客地址:" + e);artlUrls.add(e);}}}结果
结语
功能实现主要技术点是
1.java http的请求、响应。
2.正则的匹配。
今天是星期六又是520,我又孤独的坐在宝安图书馆三楼期刊后面的角落,又默默的写着这无聊到蛋疼的程序、以及教别人如何写这无聊到蛋疼的博客,念及此不觉潸然泪下。
代码地址:https://code.csdn.net/luo4105/study_http/tree/history/src/main/java/com/lc/https/AddCsdnBlogPV.java
- http编程系列(二)——java爬虫实现刷个人博客的访问量
- 爬虫 博客 增加访问量 Jsoup Java 正则 实现
- 简单CSDN爬虫,实现博客访问量记录
- python爬虫设计刷博客访问量(刷访问量,赞,爬取图片)
- python爬虫之csdn刷博客访问量
- PHP爬虫之刷博客访问量
- Django学习(二)——实现个人博客网站
- 爬虫入门系列(二):优雅的HTTP库requests
- 妈妈再也不用担心我的博客访问量了(一个可以刷博客访问量的小程序java)
- 如何刷博客的访问量
- 如何刷博客的访问量
- 网络编程笔记二:一个java爬虫的实现(静态页面)
- javaSE_8系列博客——Java语言的特性(二)--高级语言的基础知识
- 庆祝CSDN的个人博客访问量排名进入100
- 庆祝CSDN的个人博客访问量排名进入50名
- 简单的Python爬虫刷访问量程序
- http编程系列(一)——URL使用和爬取博客图片小DEMO
- J2EE系列:Java网络爬虫的实现
- Unite 2017 干货整理 优化篇
- WebView你可能不知道的细节
- NS2相关学习——可靠的MANET应用程序的Gossip协议分析
- Echarts的使用以及动态加载数据
- 事务
- http编程系列(二)——java爬虫实现刷个人博客的访问量
- 182
- POJ-3126 Prime Path ( BFS )
- Spring Ehcache 整合
- BT 4.2 蓝牙工具之工欲善其事必先利其器
- [均摊 线段树] UOJ#228. 基础数据结构练习题
- Spring AOP环绕通知小例子
- JDBC_数据库连接池
- 错题本系统