Java爬取校内论坛新帖

为了保持消息灵通,博主没事会上上校内论坛看看新帖,作为爬虫爱好者,博主萌生了写个爬虫自动下载的想法。

嗯,这次就选Java。

第三方库准备

Jsoup

Jsoup是一款比较好的Java版HTML解析器。可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

mysql-connector-java

mysql-connector-java是java JDBC的MySQL驱动,可以提供方便统一的接口来操纵MySQL数据库

爬虫步骤

目标分析

爬取网页

解析网页

存储数据

目标分析

博主爬取的是浙大的cc98论坛,需要内网才能上,新帖会在其中一个版面内出现,界面大概是这样:

分析一下之后,发现100条新帖一共有5页,内容呈现在一张表格上。

再用Firefox分析一下页面,发现是一个class="tableborder1"的table下有20行记录,每一行有4个td,爬虫只要获取这四个td数据就可以了。

爬取网页

由于这个网站是要用用户名和密码登录的,博主一开始都在使用POST方法,后来用Firefox抓包分析之后,才发现可以使用带cookies的GET方法登录。

private void getDoc(String url, String page)

{

try

{

//获取网页

this.doc = Jsoup.connect(url)

.cookie("aspsky", "***")

.cookie("BoardList","BoardID=Show")

.cookie("owaenabled","True")

.cookie("autoplay","True")

.cookie("ASPSESSIONIDSSCBSSCR","***")

.data(" stype","3")

.data("page",page) //Page就是1-5页

.get();

}

catch (IOException e)

{

e.printStackTrace();

throw new RuntimeException();

}

}

这里使用到的Jsoup很强大,其实还可以添加header之类的作修饰,但博主发现只要加了cookies之后就能成功访问了。

解析网页

根据目标分析的结果,我们可以开始解析HTML文档,同样地,Jsoup允许使用JQuery方法来解析,十分方便

private void parse()

{

//采用JQuery CSS选择

Elements rows = doc.select(".tableborder1 tr");

//去掉表头行

rows.remove(0);

for(Element row : rows)

{

String theme = row.select("td:eq(0) a:eq(1)").text().trim();

String url = "http://www.cc98.org/"

+ row.select("td:eq(0) a:eq(1)").attr("href");

String part = row.select("td:eq(1) a").text().trim();

String author = row.select("td:eq(2) a").text().trim();

if(author.length()==0)

{

author = "匿名";

}

String rawTime = row.select("td:eq(3)").text().

replace("\n","")

.replace("\t","");

try

{

Date publishTime = sdf.parse(rawTime);

System.out.println(publishTime+" "+theme);

System.out.println("---------------------------------------------------------");

storage.store(theme,publishTime,part,author,url);

}

catch (ParseException e)

{

e.printStackTrace();

}

}

}

存储数据

为了方便日后的分析(博主还打算偶尔分析一下各个版面的活跃情况),我们要把数据存储到硬盘上,这里选用了jdbc连接MySQL

public void store(String theme, Date publishTime,

String part, String author,

String url)

{

try

{

String sql = "INSERT INTO news (theme," +

"publishTime,part,author,url)VALUES(?,?,?,?,?)";

//使用预处理的方法

PreparedStatement ps = null;

ps = conn.prepareStatement(sql);

//依次填入参数

ps.setString(1,theme);

java.sql.Time time = new java.sql.Time(publishTime.getTime());

//这里使用数据库的时间戳

ps.setTimestamp(2,new Timestamp(publishTime.getTime()));

ps.setString(3,part);

ps.setString(4,author);

ps.setString(5,url);

ps.executeUpdate();

}

catch (SQLException e)

{

//主要是重复的异常,在MySQL中已经有约束unique

// e.printStackTrace();

}

}

我们可以通过MySQL可视化工具查看结果,由于MySQLworkbench不太好用,博主使用了DBeaver,结果如下:

结果非常令人满意。

完整代码

Spider.java

package com.company;

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.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

public class Spider

{

private Document doc;

//定义时间格式

private SimpleDateFormat sdf = new SimpleDateFormat( "  yyyy/MM/dd  HH:mm " );

Storage storage = new Storage();

private void getDoc(String url, String page)

{

try

{

//获取网页

this.doc = Jsoup.connect(url)

.cookie("aspsky", "***")

.cookie("BoardList","BoardID=Show")

.cookie("owaenabled","True")

.cookie("autoplay","True")

.cookie("ASPSESSIONIDSSCBSSCR","***")

.data(" stype","3")

.data("page",page)

.get();

}

catch (IOException e)

{

e.printStackTrace();

throw new RuntimeException();

}

}

private void parse()

{

//采用JQuery CSS选择

Elements rows = doc.select(".tableborder1 tr");

//去掉表头行

rows.remove(0);

for(Element row : rows)

{

String theme = row.select("td:eq(0) a:eq(1)").text().trim();

String url = "http://www.cc98.org/"

+ row.select("td:eq(0) a:eq(1)").attr("href");

String part = row.select("td:eq(1) a").text().trim();

String author = row.select("td:eq(2) a").text().trim();

if(author.length()==0)

{

author = "匿名";

}

String rawTime = row.select("td:eq(3)").text().

replace("\n","")

.replace("\t","");

try

{

Date publishTime = sdf.parse(rawTime);

System.out.println(publishTime+" "+theme);

System.out.println("---------------------------------------------------------");

storage.store(theme,publishTime,part,author,url);

}

catch (ParseException e)

{

e.printStackTrace();

}

}

}

public void run(String url)

{

for (Integer i = 1; i<=5; i++)

{

getDoc(url, i.toString());

parse();

}

storage.close();

}

public static void main(String[] args)

{

Spider spider = new Spider();

spider.run("http://www.cc98.org/queryresult.asp?stype=3");

}

}

Storage.java

package com.company;

import java.sql.*;

import java.util.Date;

public class Storage {

//数据库连接字符串,cc98为数据库名

private static final String URL="jdbc:mysql://localhost:3306/cc98?characterEncoding=utf8&useSSL=false";

//登录名

private static final String NAME="***";

//密码

private static final String PASSWORD="***";

private Connection conn = null;

public Storage()

{

//加载jdbc驱动

try

{

Class.forName("com.mysql.jdbc.Driver");

}

catch (ClassNotFoundException e)

{

System.out.println("未能成功加载驱动程序,请检查是否导入驱动程序!");

e.printStackTrace();

}

try

{

conn = DriverManager.getConnection(URL, NAME, PASSWORD);

// System.out.println("获取数据库连接成功!");

}

catch (SQLException e)

{

// System.out.println("获取数据库连接失败!");

e.printStackTrace();

}

}

public void close()

{

//关闭数据库

if(conn!=null)

{

try

{

conn.close();

}

catch (SQLException e)

{

e.printStackTrace();

}

}

}

public void store(String theme, Date publishTime,

String part, String author,

String url)

{

try

{

String sql = "INSERT INTO news (theme," +

"publishTime,part,author,url)VALUES(?,?,?,?,?)";

//使用预处理的方法

PreparedStatement ps = null;

ps = conn.prepareStatement(sql);

//依次填入参数

ps.setString(1,theme);

java.sql.Time time = new java.sql.Time(publishTime.getTime());

//这里使用数据库的时间戳

ps.setTimestamp(2,new Timestamp(publishTime.getTime()));

ps.setString(3,part);

ps.setString(4,author);

ps.setString(5,url);

ps.executeUpdate();

}

catch (SQLException e)

{

//主要是重复的异常,在MySQL中已经有约束unique

// e.printStackTrace();

}

}

}

小结

这个项目其实涉及的知识点还挺多的,博主也刚学java,很多细节也没有很好吃透,如JDBC、Jsoup都值得好好学习一下。欢迎大家批评指正。

另,祝大家中秋国庆双节快乐~

Java爬取先知论坛文章

Java爬取先知论坛文章 0x00 前言 上篇文章写了部分爬虫代码,这里给出一个完整的爬取先知论坛文章代码. 0x01 代码实现 pom.xml加入依赖: & ...

【Python】爬取理想论坛单帖爬虫

代码: # 单帖爬虫,用于爬取理想论坛帖子得到发帖人,发帖时间和回帖时间,url例子见main函数 from bs4 import BeautifulSoup import requests impo ...

Java爬取B站弹幕 —— Python云图Wordcloud生成弹幕词云

一 . Java爬取B站弹幕 弹幕的存储位置 如何通过B站视频AV号找到弹幕对应的xml文件号 首先爬取视频网页,将对应视频网页源码获得 就可以找到该视频的av号aid=8678034 还有弹幕序号, ...

MinerHtmlThread&period;java 爬取页面线程

MinerHtmlThread.java 爬取页面线程 package com.iteye.injavawetrust.miner; import org.apache.commons.logging ...

MinerConfig&period;java 爬取配置类

MinerConfig.java 爬取配置类 package com.iteye.injavawetrust.miner; import java.util.List; /** * 爬取配置类 * @ ...

Java爬取网络博客文章

前言 近期本人在某云上购买了个人域名,本想着以后购买与服务器搭建自己的个人网站,由于需要筹备的太多,暂时先搁置了,想着先借用GitHub Pages搭建一个静态的站,搭建的过程其实也曲折,主要是域名地 ...

java爬取网页内容 简单例子(2)——附jsoup的select用法详解

[背景] 在上一篇博文java爬取网页内容 简单例子(1)——使用正则表达式 里面,介绍了如何使用正则表达式去解析网页的内容,虽然该正则表达式比较通用,但繁琐,代码量多,现实中想要想出一条简单的正则表 ...

java爬取并下载酷狗TOP500歌曲

是这样的,之前买车送的垃圾记录仪不能用了,这两天狠心买了好点的记录仪,带导航.音乐.蓝牙.4G等功能,寻思,既然有这些功能就利用起来,用4G听歌有点奢侈,就准备去酷狗下点歌听,居然都是需要办会员才能下 ...

Java爬取并下载酷狗音乐

本文方法及代码仅供学习,仅供学习. 案例: 下载酷狗TOP500歌曲,代码用到的代码库包含:Jsoup.HttpClient.fastJson等. 正文: 1.分析是否可以获取到TOP500歌单 打开 ...

随机推荐

python-selenium之firefox、Chrome、Ie运行

测试脚本是否支持在不同浏览器运行firefox浏览器运行脚本 from selenium import webdriver driver=webdriver.Firefox() driver.get( ...

【转】arcgis server site 快速恢复与重建

作者:suwenjiang 出处:http://www.cnblogs.com/myyouthlife/ 具体链接:http://www.cnblogs.com/myyouthlife/p/48985 ...

【UVA 1583】Digit Generator

题 题意 a加上 a的各位数=b,则b是a的digitSum,a是b的generator,现在给你digitSum,让你求它的最小的generator. 分析 一种方法是: 预处理打表,也就是把1到1 ...

git学习之remote

修改远程仓库:$ git remote set-url --push [name] [newUrl] git pull 的时候报错 fatal: Authentication failed for ' ...

java新手笔记29 读取文件

1.读取文件 package com.yfs.javase; import java.io.FileInputStream; import java.io.FileReader; import jav ...

研究在SAE上搭建最新wordpress

安装SAE上的wordpress,创建应用选择wordpress模板,安装后是3.4版本 新建一个版本2,下载最新wordpress安装包并解压到版本2中 初步猜想修改地方: 数据库配置:wp-con ...

VGO新闻 - VGO

VGO新闻 - VGO VGO天津伊势丹店盛装揭幕 VGO天津伊势丹店盛装揭幕2013年9月7日,VGO(微高)全国首家实体店在天津伊势丹百货盛装开幕.现场,100多位商场领导及业内同仁共同出席了

配置wamp环境使得在命令行下也能执行socket扩展

首先在apache中开启socket扩展 php环境安装目录\bin\apache\apache2.2.17\bin\php.ini 去掉前面的';'   extension=php_sockets. ...

从零开始学习前端JAVASCRIPT — 2、JavaScript基础ES5

1:ES5简介 ECMAScript 5.1 (或仅 ES5) 是ECMAScript(基于JavaScript的规范)标准的修正. 与HTML5规范进程本质类似,ES5通过对现有JavaScript ...

java爬取论坛信息_Java爬取校内论坛新帖相关推荐

  1. 用java爬取学校数据_Java爬取校内论坛新帖

    Java爬取校内论坛新帖 为了保持消息灵通,博主没事会上上校内论坛看看新帖,作为爬虫爱好者,博主萌生了写个爬虫自动下载的想法. 嗯,这次就选Java. 第三方库准备 Jsoup Jsoup是一款比较好 ...

  2. java取模负数_JAVA中取模的问题

    ## Java取模(%)运算 > [上篇文章](https://yebukong.com/article/1101070795486109697.html "上篇文章") 提 ...

  3. java实现获取各网站的机票信息_java爬取某个机票查询网站上面的信息(刚学!!!)...

    [Java] 纯文本查看 复制代码[ 本帖最后由 shangjS009 于 2018-5-25 15:41 编辑 ]\n\n@RequestMapping(value = "${adminP ...

  4. python爬取商品信息_python爬取商品信息

    原博文 2014-11-27 02:09 − 老严要爬某网购网站的商品信息,正好我最近在学python,就一起写了一个简单的爬虫程序. 需求:某网的商品信息,包括商品名,市场价和售价 工具:pytho ...

  5. python爬取招聘信息_python 爬取boss直聘招聘信息实现

    原标题:python 爬取boss直聘招聘信息实现 1.一些公共方法的准备 获取数据库链接: importpymysql ''' 遇到不懂的问题?Python学习交流群:821460695满足你的需求 ...

  6. python爬取旅游信息_Python 爬取 13 个旅游城市,告诉你五一大家最爱去哪玩?

    五一假期已经结束,小伙伴是不是都还没有玩过瘾?但是没办法,还有很多bug等着我们去写,同样还有需要money需要我们去赚.为了生活总的拼搏. 今年五一放了四天假,很多人不再只是选择周边游,因为时间充裕 ...

  7. python爬取个人信息_Python爬取个人微信朋友信息操作示例

    本文实例讲述了Python爬取个人微信朋友信息操作.分享给大家供大家参考,具体如下: 利用Python的itchat包爬取个人微信号的朋友信息,并将信息保存在本地文本中 思路要点: 1.利用itcha ...

  8. python爬取身份证信息、爬取ip代理池

    匹配的分类 按照匹配内容进行匹配 我们在匹配的过程当中,按照要匹配的内容的类型和数量进行匹配 比如: 匹配手机号:匹配以1开头的11位数字 Re 按照匹配结构进行匹配 我们我们在匹配的过程当中,按照要 ...

  9. python爬取旅游信息_python爬取全国13个城市旅游数据,告诉你那里最受欢迎

    抓取数据 通过请求https://piao.qunar.com/ticket/list.htm?keyword=北京,获取北京地区热门景区信息,再通过BeautifulSoup去分析提取出我们需要的信 ...

最新文章

  1. 专访英特尔AIPG全球研究负责人Casimir Wierzynski:物理学、隐私和大脑将根本性塑造AI
  2. localparam和parameter的区别
  3. Android JetPack ViewModel 源码解析
  4. 我说分布式事务之消息最终一致性事务(一):原理及实现
  5. Python:numpy库中的一些函数简介、使用方法之详细攻略
  6. python xlwt写入数据超过范围限制_python的xlwt不能正确写入以及缓冲区问题
  7. linux 安装tomcat 权限不足问题
  8. 用私有构造器或者枚举类型强化Singleton 属性
  9. LeetCode 344 反转字符串
  10. 获取【请求体】数据的3种方式 request.getInputStream() request.getInputStream() request.getReader()
  11. DockerFile : COPY 和 ADD 命令不能拷贝上下文之外的本地文件
  12. MyBatis 简介
  13. OpenGL的几何变换[转]
  14. vscode选择python解释器
  15. vue-devtools 必备开发工具
  16. 一图搞懂梯度、散度、旋度、Jacobian、Hessian、Laplacian之间的关系
  17. android camera2美颜,Nano Camera(多功能美颜相机)V2.1 安卓版
  18. JavaScript-⑤代码
  19. 腾讯防水墙的使用(python_web)
  20. gcc中的 -I -L(大写l) -l(小写l) -Wl,-rpath 选项

热门文章

  1. sklearn 中F1-score的计算
  2. 工具类 - 思维导图
  3. 学习大数据分析要什么基础,零基础入门ok吗?
  4. 显示器手调对比度算法介绍
  5. linux文件搜索关键字并显示前后10行
  6. 农场工具程序设计(三)
  7. 单例模式 Windows下防止多开简介
  8. 自定义桌面开始按钮(winxp、7、8、8.1、10)
  9. 打印表格打印机没有反应_打印机没反应怎么回事
  10. JS根据日期计算年龄