前提:因为一直在和朋友做网站
看门猪返利网 ,使用的程序本身并不能从广告联盟抓取商城数据,一个一个添加几百个都手动也不靠谱,程序员出身就决定出手一试。
使用到的开源包:
httpclient 做自动登录,网页抓取
jsoup 解析网页,获取目标信息,配合httpclient进行尝试网页抓取
jetty 抓取到的信息需要展示,使用传统应用程序展示要考虑的东西多,还是网页展示简单,就使用jetty做内嵌。
slf4j 用都知道,包小好用。
velocity 做网页模板
jsoup 也能直接抓取网页,但在cookie维持这一块跟httpclient差远了,所以我就只用jsoup解析抓取的网页。
登录:
HttpClient httpclient = new DefaultHttpClient();
//httpclient.getParams().setParameter(HTTP.CONTENT_ENCODING, "UTF-8");
String url="http://www.kanmenzhu.com/user/login.php";
HttpPost client=new HttpPost(url);
List nvList=new ArrayList(2);
nvList.add(new BasicNameValuePair("user","u"));
nvList.add(new BasicNameValuePair("password","p"));
client.setEntity(new UrlEncodedFormEntity(nvList, "UTF-8"));
logger.info("尝试登录"+host);
HttpResponse response=httpclient.execute(client);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
logger.info("成功登录"+host);
//String res=EntityUtils.toString(entity);
//logger.info(res);
}else{
logger.warn("登录失败");
System.exit(0);
}
解析:
logger.info("开始广告分析列表.....");
//这是第一页的链接
url="http://www.kanmenzhu.com/malllist.php";
Document doc=HttpPageTools.getJsoupDocByUrl(httpclient, url+"&p=1");
//这是工具类方法 另一个类中的
public static Document getJsoupDocByUrl(HttpClient httpclient,String url){
HttpGet hg=new HttpGet(url);
HttpResponse response;
try {
response = httpclient.execute(hg);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
HttpEntity entity = response.getEntity();
String res=EntityUtils.toString(entity);
EntityUtils.consume(entity);
//logger.info(res);
Document doc=Jsoup.parse(res);
return doc;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//工具类方法
if(doc!=null){
int pageCount=MaiPraser.getPageInfo(doc);
logger.info("总共:"+pageCount+"页,当前第1页");
Map cpsMap=new HashMap();//放所有广告
for(int i=2;i<=pageCount;i++){
doc=HttpPageTools.getJsoupDocByUrl(httpclient, url+"&p="+i);//见上面的工具类抓取代码
logger.info("总共:"+pageCount+"页,当前第"+i+"页");
cpsMap.putAll(MaiPraser.prase(doc,host));//把解析的每一页都加进去
}
logger.info("广告列表分析完毕,共"+cpsMap.size()+"个广告商,开始分析单个广告商信息.....");
//根据解析到的链接,再进入到详页抓信息
for(MyCPS dp:cpsMap.values()){
String detailLink=dp.getCpsDetail();
//logger.info("要抓取的链接:"+detailLink);
HttpGet thg=new HttpGet(detailLink);
HttpResponse httpResp=httpclient.execute(thg);
if(httpResp.getStatusLine().getStatusCode()==HttpStatus.SC_OK){//成功获取到 了
Thread.sleep(200);
HttpEntity respBody=httpResp.getEntity();
//logger.info(EntityUtils.toString(respBody));
Document ddoc=Jsoup.parse(EntityUtils.toString(respBody));
EntityUtils.consume(httpResp.getEntity());
MaiPraser.praseDetail(dp, ddoc, host);//详细解析代码,见解析代码示例
}logger.info("广告商已解析完成:"+dp.getName());MainServlet.addData(dp);// 这是我Servlet 中的一个list}}
获取总页数信息
*/
public static int getPageInfo(Document doc){
Elements elements=doc.select("td[class$=foot_page]");//这就是jsoup语法,很像jquery
String href=elements.first().select("a[class$=page_last]").attr("href");
int result=Integer.valueOf((href.substring(href.lastIndexOf("=")+1)));
//logger.info(href);
return result;
}
public static void praseDetail(MyCPS dmc,Document doc_detail,String host){
for(Element ne:doc_detail.select("div[class$=ad_newteach]")){
String u=ne.childNode(1).attr("src");
u=host+u;
dmc.setImg(u);
//图片logger.info(ne.childNode(1).attr("src"));
dmc.setName(((Element)ne.childNode(3)).text());
//名称logger.info(((Element)ne.childNode(3)).text());
dmc.setUrl(((Element)ne.childNode(5)).child(0).attr("href"));
//网站logger.info(((Element)ne.childNode(5)).child(0).attr("href"));
//String adids=((Element)ne.childNode(7)).child(0).attr("href");
//logger.info(adids=adids.substring(adids.lastIndexOf('=')+1));
// MainServlet.addData(ne.childNode(1).toString());
//if(ne.tagName().equals("img")){
// logger.info(ne.childNode(0));
//}
}
for(Element ne:doc_detail.select("div[class$=ad_zhu]")){
//简介logger.info(ne.text());
dmc.setMemo(ne.text());
}
}
public class WebServerStarter {
private static Logger logger=LoggerFactory.getLogger(WebServerStarter.class);
public static void main(String[] args) {
Server server=new Server();
Connector conn = new SelectChannelConnector();
if(args!=null)
conn.setPort(Integer.valueOf(args[0]));
server.setConnectors(new Connector[] {conn});
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.addServlet(new ServletHolder(new MainServlet()), "/*");//MainServlet 就是我的一个servlet,就这么简单。
webapp.setWar("./webapps"); //如需指定war目录,则相对应地在工程目录下建立一同名目录,否则启动时会产生异常
server.setHandler(webapp);
try {
server.start();
} catch (Exception e) {
logger.error("可能是端口冲突了,请检查端口配置",e);
System.exit(0);
}
}
}
展示:
展示就比较简单了,把信息往VM中一填再展示就行了