📄 parser.java
字号:
/*
* *****************************************************
* Copyright (c) 2005 IIM Lab. All Rights Reserved.
* Created by xuehao at 2005-10-12
* Contact: zxuehao@mail.ustc.edu.cn
* *****************************************************
*/
package org.indigo.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.httpclient.NameValuePair;
import org.indigo.util.MainConfig;
/**
* 解析通过URL指定的页面类。
* @author wbz
*
*/
public class Parser
{
private URL itsUrl=null;
private HttpURLConnection itsConn = null;
// private NavigateController itsNav=null;
private String itsEncoding=null;
private final String DEFAULT_ENCODING = "gb2312";
private String itsPageStr=null;
private boolean IsByPost=false;
private NameValuePair data[]=null;
private String itsFormUrl=null;
private boolean IsByLogin=false;
private String itsOtherUrl=null;
public Parser()
{
}
/**
* 此方法通过指定开始和结束标记来获取有用的信息,这样可以去掉一些不需要信息的干扰。
* add by wbz for getting a userful infomation body from a homepage;
* setItsPageStr
* @param startStr
* @param endStr
*/
public void setItsPageStr(String startStr, String endStr)
{
itsPageStr=parseWith(startStr, endStr);
}
/**
* 设置是否需要登录的参数。
* @param IsByLogin
*/
public void setIsByLogin(boolean IsByLogin)
{
this.IsByLogin=IsByLogin;
}
/**
* 设置在提交表单时,需要的参数。
* @param data
*/
public void setJSValuePairs(NameValuePair data[])
{
this.data=data;
}
/**
* 根据指定的开始标记和结束标记,获取开始和结束标记中间的内容。
* @param startStr 开始标记
* @param endStr 结束标记
* @return
*/
public String parseWith(String startStr, String endStr)
{
// System.out.println( itsUrl );
startStr = startStr.trim();
endStr = endStr.trim();
String midStr=null;
int i;
if( itsPageStr==null )
return null;
i = itsPageStr.indexOf( startStr );
if( i==-1 )
return null;
itsPageStr = itsPageStr.substring( i+startStr.length() );
i = itsPageStr.indexOf( endStr );
if( i==-1 )
return null;
midStr = itsPageStr.substring( 0, i );
return midStr;
}
/**
* 当采集规则中用到正则表达式时,需要调用此方法。
* 此方法中的前后标识是用正则表达式表示的。
* @param startRex 含有正则表达式的前标识。
* @param endRex 含有正则表达式的后标识。
* @return
*/
public String parserWithRegex(String startRex,String endRex)
{
Pattern spattern = Pattern.compile(startRex);//("<td align=\"center\" bgcolor=\"[0-9a-fA-F]{6}\">");//\\s*.*([\u4e00-\u9fa5]+)</td>");
Pattern bpattern=Pattern.compile(endRex);
Matcher m=spattern.matcher(itsPageStr);
int s=-1;
String midStr=null;
if(m.find())
{
// System.out.println(m.group());
s=m.start()+m.group().length();
itsPageStr=itsPageStr.substring(s);
m=bpattern.matcher(itsPageStr);
if(m.find())
{
midStr=itsPageStr.substring(0, m.start());//m.group(1);
itsPageStr=itsPageStr.substring(midStr.length()+m.group().length());
}
// System.out.println(midStr);
}
return midStr;
}
/**
* 设置在通过提交表单的形式访问页面时需要指定的处理页面的URL。
* @param url
*/
public void setFromUrl(String url)
{
//setUrl(url);
itsFormUrl=url;
}
/**
* 设置需要采集的URL。
* @param url
*/
public void setUrl(String url)
{
if(IsByPost)//通过提交的形式访问页面时。
{
url=url.replaceAll(" ", "");
itsFormUrl=url;
return;
}else if(IsByLogin)//通过登录的方式访问页面时。
{
url=url.replace(" ", "");
itsOtherUrl=url;
return;
}
url=url.replaceAll(" ", "");
itsUrl = null;
/**
* 和指定的URL建立连接。
*/
try
{
itsUrl = new URL( url );
itsConn = (HttpURLConnection)itsUrl.openConnection();
// System.out.println( "Parser with: " + url );
} catch (MalformedURLException e)
{
e.printStackTrace();
}catch (IOException e1)
{
e1.printStackTrace();
}
return;
}
/**
* 打开指定URL的连接。
* @return
*/
public boolean open()
{
if(IsByPost)//当通过提交的方式访问URL时,通过此代码段获取源文件。
{
itsPageStr=Login.getHtmlByPost(itsFormUrl,data);
}
else if(IsByLogin)//当通过登录的方式访问URL时,通过此代码段获取源文件。
{
itsPageStr=Login.getHtmlByLogin(itsFormUrl, data, itsOtherUrl);
}
else//一般情况下,通过下面的代码段获取源文件。
itsPageStr = parseAll();
if( itsPageStr==null )
return false;
return true;
}
/**
* 使获取的源文件置null
*
*/
public void close()
{
itsPageStr = null;
}
/**
* 设置是否通过提交获取页面。
* @param IsByPost
*/
public void setIsByPost(boolean IsByPost)
{
this.IsByPost=IsByPost;
}
public String OtherParserAll(String classname)
{
return null;
}
/**
* 在一般的情况下,获取指定页面的源代码。
* @return
*/
public String parseAll()
{
if( itsUrl==null || itsConn==null )
return null;
int retryCount=1;
//当指定页面访问无法连接时,需要再次尝试,此参数是指定重新尝试次数。
String retryStr = MainConfig.getInstance().getProperty("RetryCount");
if( retryStr==null || retryStr.equals("") )
{
retryCount = 1;
}else
retryCount = Integer.parseInt( retryStr );
int m = retryCount;
BufferedReader rd = null;
int k=0;
boolean retryFlag = false;
while( k<retryCount )
{
try
{
if( itsEncoding==null )
itsEncoding = DEFAULT_ENCODING;
itsConn.disconnect();
itsConn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows 2000)");
itsConn.connect(); //建立连接。
//System.out.println( itsConn.getContentEncoding() );
// Map map=itsConn.getHeaderFields();
// Iterator it=map.keySet().iterator();
// while (it.hasNext())
// System.out.println(itsConn.getHeaderField((String)it.next()));
String charset=itsConn.getHeaderField("Content-Type");
int kk=-1;
if(charset!=null&&(kk=charset.indexOf("charset="))!=-1)
{
charset=charset.substring(kk+8);
itsEncoding=charset;
}
rd = new BufferedReader( new InputStreamReader( itsConn.getInputStream(), itsEncoding ) );
if( rd!=null )
{
break;
// retryCount = 0;
}
} catch (IOException e)
{
// TODO Auto-generated catch block
// e.printStackTrace();
retryFlag = true;
retryCount--;
// System.out.println("");
System.out.println( itsUrl + " [left retry " + retryCount + "]" );
}
}
if( retryFlag )
{
System.out.println( itsUrl + " [ get at retry" + (m-retryCount) + "]" );
}
if( rd==null )
{
System.out.println( "donot get the page." );
return null;
}
String str;
StringBuffer pageStr=new StringBuffer();
int i=0;
try
{
while( (str=rd.readLine())!=null )
{
i++;
// System.out.print( "." );
pageStr.append( str.trim() );
}
} catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
// System.out.println( "\nline=" + i );
try
{
rd.close();
} catch (IOException e2)
{
// TODO Auto-generated catch block
e2.printStackTrace();
}
itsConn.disconnect();//源代码成功获取,断开连接。
itsPageStr = pageStr.toString();
// System.out.println( itsPageStr );
// System.out.println( "parse all over" );
return itsPageStr;
}
public void setItsEncoding(String itsEncoding) {
this.itsEncoding = itsEncoding;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -