又到了毕业季,在写人文讲座听后感的时候搜集之前听过的讲座信息总是一件很麻烦的事情,为了避免重复劳动,写了一个小爬虫来帮我搜集听过的人文讲座的相关信息,方便我来写听后感。
爬虫的程序入口是Entrance类,里面只有一个main函数,输入你听过的讲座的时间(时间可以通过一卡通中心,或者小猴偷米微信查询得到),就能输出与时间对应的讲座的信息所在的网址。你也可以选择直接打开相关的网页。
与之前的爬虫一样,这个爬虫是基于Jsoup框架的,需要导入Jsoup类。
Jsoup度盘地址:http://pan.baidu.com/s/1dDxXnsH
代码在下面,也可以去github上直接找整个工程
https://github.com/multiangle/SEU-Lecture-Spider
1.Entrance类
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
public class Entrance {
public static void main(String[] args){
ArrayList<Date> date=new ArrayList() ;
ArrayList<Message> message=new ArrayList() ;
date.add(new Date(2015,4,16)) ;
date.add(new Date(2015,4,8)) ;
date.add(new Date(2015,3,23)) ;
date.add(new Date(2015,4,21)) ;
date.add(new Date(2015,4,20)) ;
date.add(new Date(2015,3,16)) ;
date.add(new Date(2014,11,21)) ;
date.add(new Date(2014,4,17)) ;
message=Message.FindMessage(date) ;
Message.println(message);
//Message.openPage(message);
}
}
这里有新项只要在后面补上date.add(….)就行了。
Message.openPage是在浏览器上打开所有符合条件的网页,一般是输入几个日期就开几个网页
2.Date类
import java.lang.Comparable;
public class Date implements Comparable<Date>{
public int year ;
public int month ;
public int day ;
public int id ;
public Date(int year,int month,int day){
this.year=year ;
this.month=month ;
this.day=day ;
this.id=date2int(year,month,day) ;
}
public static String outStandard(int input){ //不论进去的是几位数,出来的统一是2位数
if (input>9){
String temp="0"+Integer.toString(input);
return temp ;
}
else{
String temp=Integer.toString(input) ;
return temp ;
}
}
public static int date2int(int year,int month,int day){
int temp2=0 ;
for(int i=2001;i<year;i++){
if (i%4==0){
temp2+=366 ;
}else
temp2+=365 ;
}
int[] monday ;
if (year%4==0){
int[] temp={31,29,31,30,31,30,31,31,30,31,30,31} ;
monday=temp ;
}else{
int[] temp={31,28,31,30,31,30,31,31,30,31,30,31} ;
monday=temp ;
}
int temp1=temp2 ;
for(int i=0;i<month-1;i++){
temp1+=monday[i] ;
}
temp1+=day ;
return temp1 ;
}
@Override
public int compareTo(Date o){
if (this==o){
return 0 ;
}
else if (o!=null && o instanceof Date){
if (this.id<=o.id) return -1 ;
else return 1 ;
}else return -1 ;
}
}
日期类,里面有与日期相关的属性和方法
3.ListPage类
import java.io.IOException;
import java.net.URL;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.jsoup.helper.Validate;
public class ListPage {
public Document content ;
public int first_time ; //最新时间
public int last_time ; //最早时间
public int[] time ;
public String[] url ;
public int current_page ;
public int total_page ;
public ListPage(int page){
String url="http://www.seu.edu.cn/138/list"+Integer.toString(page)+".htm" ;
Document tc1=getPage(url) ; //temp_content_1
Element e_news=tc1.getElementById("wp_news_w3") ;
Elements list=e_news.child(0).child(0).children();
int len=list.size()/2 ;
this.time=new int[len] ;
this.url=new String[len] ;
for (int i=0;i<len;i++){
Elements e=list.get(i*2).getElementsByAttributeValue("align", "left") ;
String stime=e.get(2).text() ;
this.time[i]=Date.date2int(Integer.parseInt(stime.substring(0, 4)),
Integer.parseInt(stime.substring(5,7)),Integer.parseInt(stime.substring(8,10))) ;
this.url[i]=e.get(1).getElementsByTag("a").first().absUrl("href") ;
}
this.first_time=this.time[0] ;
this.last_time=this.time[this.time.length-1] ;
Element e_paging=tc1.getElementById("wp_paging_w3") ;
Element li=e_paging.getElementsByTag("li").get(2) ;
this.current_page=Integer.parseInt(li.getElementsByClass("curr_page").first().text()) ;
this.total_page=Integer.parseInt(li.getElementsByClass("all_pages").first().text()) ;
}
public static void main(String[] args){
String url="http://www.seu.edu.cn/138/list"+Integer.toString(1)+".htm" ;
Document tc1=getPage(url) ; //temp_content_1
Element e_paging=tc1.getElementById("wp_paging_w3") ;
System.out.println(e_paging.getElementsByTag("li").get(2).getElementsByClass("all_pages").first().text()) ;
}
public static Document getPage_inner(String url) throws IOException{
Document doc ;
try{
doc = Jsoup.parse(new URL(url).openStream(), "UTF-8", url);
//doc=Jsoup.connect(url).get() ;
return doc ;
}catch(IOException e){
return null;
}
}
public static Document getPage(String url){
try{
Document doc ;
int times=0 ;
//System.out.println("正在请求获取网页"+url);
doc=getPage_inner(url) ;
while(doc.equals(null)&×<8){
doc=getPage_inner(url) ;
System.out.println("第"+times+"次请求失败,正在进行第"+(++times)+"次请求");
}
if (doc.equals(null)){
System.out.println("ERROR:获取网页失败");
return null ;
}else{
return doc ;
}
}catch(IOException e){
return null ;
}
}
}
处理列表网页的类,有自动重连功能,不至于一次网络波动没连上导致整个程序奔溃。
4.Message类
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Message {
public String url ;
public Date date ;
public Message(){}
public Message(Date date){
this.date=date ;
this.url="Not Found" ;
}
public Message(Date date,String url){
this.date=date ;
this.url=url ;
}
public static void println(ArrayList message){
int len=message.size() ;
for(int i=0;i<len;i++){
Message m=(Message)message.get(i) ;
System.out.println(m.date.year+"年"+m.date.month+"月"+m.date.day+"日\t"+m.url);
}
}
public static void openPage(ArrayList message){
int len=message.size() ;
for(int i=0;i<len;i++){
Message m=(Message)message.get(i) ;
if (!m.url.contains("Not Found")){
java.net.URI uri;
try {
uri = new java.net.URI(m.url);
java.awt.Desktop.getDesktop().browse(uri);
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static ArrayList FindMessage(List inDate){
Collections.sort(inDate); //将输入数列按照增序排序
Collections.reverse(inDate);
ArrayList<Message> message=new ArrayList() ;
ListPage current_lp=new ListPage(1) ;
int current_page_num=current_lp.current_page ;
int total_page_num=current_lp.total_page ;
for(int i=0;i<inDate.size();i++){
Date d=(Date)inDate.get(i) ;
while(true){
if (d.id<=current_lp.first_time && d.id>=current_lp.last_time){
break ;
}
else{
if (current_page_num>=total_page_num) break ;
else{
current_page_num++ ;
current_lp=new ListPage(current_page_num) ;
}
}
}
if (current_page_num>=total_page_num) System.out.println("日期输入错误") ;
else{
if (current_lp.last_time>=(d.id-7)){ //要横跨两页的情况
boolean sig=false ;
for(int j=0;j<current_lp.time.length;j++){
if (current_lp.time[j]<=d.id && current_lp.time[j]>=(d.id-7)){
sig=new innerPage(current_lp.url[j],d).isCorrect ;
if (sig){
Message m=new Message(d,current_lp.url[j]) ;
message.add(m) ;
break ;
}
}
}
ListPage temp_lp=new ListPage(current_page_num+1) ;
for(int j=0;j<temp_lp.time.length;j++){
if (temp_lp.time[j]<=d.id && temp_lp.time[j]>=(d.id-7)){
sig=new innerPage(temp_lp.url[j],d).isCorrect ;
if (sig){
Message m=new Message(d,temp_lp.url[j]) ;
message.add(m) ;
break ;
}
}
}
if (!sig) {
Message m=new Message(d) ;
message.add(m) ;
}
}else{ //在一页内的情况
boolean sig=false ;
for (int j=0;j<current_lp.time.length;j++){
if (current_lp.time[j]<=d.id && current_lp.time[j]>=(d.id-7)){ //初步检查日期是否符合
innerPage ip=new innerPage(current_lp.url[j],d) ;
sig=ip.isCorrect ;
if (sig){
Message m=new Message(d,current_lp.url[j]) ;
message.add(m) ;
break ;
}
}
}
if (!sig) {
Message m=new Message(d) ;
message.add(m) ;
}
}
}
}
return message ;
}
}
Entrance类的main函数直接执行Message类中的FindMessage方法来调度其他各个类
5.innerPage类
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class innerPage {
public boolean isCorrect ;
public innerPage(String url,Date date){
this.isCorrect=false ;
if (url.contains("www.seu.edu.cn")){
//System.out.println(url);
Document tc1=ListPage.getPage(url) ;
Element ac=tc1.getElementsByClass("Article_Content").first() ;
Elements p ;
if (ac.getElementsByTag("p").size()<5){
p=ac.getElementsByTag("div") ;
}else{
p=ac.getElementsByTag("p") ;
}
for(Element tp:p){
String temp=tp.text().replace(Jsoup.parse(" ").text(), "") ;
temp=temp.replace(" ", "") ;
String sdate_1=Integer.toString(date.month)+"月"+Integer.toString(date.day)+"日" ;
String sdate_2=Integer.toString(date.month)+"月"+Date.outStandard(date.day)+"日" ;
String sdate_3=Integer.toString(date.day)+"日" ;
if (temp.contains(sdate_1)||temp.contains(sdate_2)||temp.contains(sdate_3)){
this.isCorrect=true ;
break ;
}
}
}
}
/*
public static void main(String[] args){
innerPage ip=new innerPage("http://www.seu.edu.cn/05/5a/c138a1370/page.htm",new Date(2014,4,4)) ;
}
*/
}
搜集具体的介绍网页,看这个网页是否是与输入时间相对应的。