使用jsoup采集网页实例

使用jsoup采集网页实例

以凤凰网为例,采集小说

参考书籍:
jsoup帮助文档 http://www.open-open.com/jsoup/
jsoup博客: http://www.jb51.net/article/43485.htm
package cn.com.metadata;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import cn.com.metadata.util.WriteToDateBase;
public class BookCollect {
private  Map<String, String> cookies = new HashMap<String, String>();
private String imagePath="D:\\image\\";
private Connection conn;
public static void main(String[] args) {
    BookCollect  bc=new BookCollect();
    //出版书库shuku.htm?yc=1&fee=1&o_type=3&f_cate=1
    StringBuffer sb1=new StringBuffer();
    sb1.append("/shuku.htm?");
    sb1.append("yc=1");
    sb1.append("&fee=1");
    sb1.append("&o_type=3");
    sb1.append("&f_cate=1");
    //原创书库shuku.htm?yc=0&f_cate=374&s_cate=716&o_type=2&fee=1&tag=
    StringBuffer sb2=new StringBuffer();
    sb2.append("/shuku.htm?");
    sb2.append("yc=0");
    sb2.append("&f_cate=374");
    sb2.append("&s_cate=716");
    sb2.append("&o_type=2");
    sb2.append("&fee=1");
    sb2.append("&tag=");
    //出版书库和原创书库详情页不一样

    for(int i=1;i<=2;i++){
        if(i==1){
            bc.collectionPage(sb1,i);//1:出版书库   2:原创书库
        }else{
            bc.collectionPage(sb2,i);//1:出版书库   2:原创书库
        }
    }


}
//分页处理采集信息
public void collectionPage(StringBuffer sb,int type){
    String baseUrl="http://v.yc.ifeng.com";
    //出版数据库
    String pageUrl=baseUrl+sb.toString();
    Document document=null;
    try {
        int pageTotal=1;
        int total=0;
        document=Jsoup.connect(pageUrl).cookies(cookies).timeout(60 * 1000).ignoreContentType(true).maxBodySize(10 * 1024 * 1024).get();
        String pageText=document.select("strong[class=f16 blue]").text();
        total=Integer.valueOf(pageText);
        if(total%20==0){
            pageTotal=total;
        }else{
            pageTotal=total/20+1;
        }
        for(int page=1;page<=pageTotal;page++){
            String str=sb.toString()+"&p="+page;
            collectIFeng(str,type);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
public  String jsoupHTML(String c,String b){
    String subStr="";
    try {
        String baseURL = "http://v.yc.ifeng.com/remc.htm?";
        StringBuffer paramsSB = new StringBuffer();
        paramsSB.append("c=");
        paramsSB.append(c);
        paramsSB.append("&b=");
        paramsSB.append(b);
        String queryURL = baseURL+paramsSB.toString();
        //获取json数据
        String InboxJson = Jsoup.connect(queryURL).cookies(cookies).timeout(60 * 1000).ignoreContentType(true).maxBodySize(10 * 1024 * 1024).post().body().html();
        InboxJson=InboxJson.replaceAll("\\\\", "");
        System.out.println("采集的文章序号:"+"/"+c+"/"+b);
        subStr=InboxJson.substring(12,InboxJson.lastIndexOf("<br>"));
        return subStr;
    } catch (Exception e) {
        e.printStackTrace();
    }
     return subStr;
}
public void collectIFeng(String params,int type){
    String urlIFeng="http://v.yc.ifeng.com";//进入凤凰网址url
    String typeUrl=urlIFeng+params;//全路径
    Document document=null;
    String fileName="";
     try {
         document=Jsoup.connect(typeUrl).cookies(cookies).timeout(60 * 1000).ignoreContentType(true).maxBodySize(10 * 1024 * 1024).get();
         Elements elements=document.select("ul[class=bimg]>li");
         for(int i=0;i<elements.size();i++){
             Element element=elements.get(i);
             //获取详情url
             String urlDetail=element.select("a").eq(0).attr("href");
             //获取图片地址
             String imgUrl=element.select("a>img").eq(0).attr("src");
             fileName=this.saveImage(imgUrl,imagePath);
             //通过详情页拿到每一个章节信息
             String detailUrl=urlIFeng+urlDetail;
             if(type==2){
                 this.connDetail(detailUrl,fileName,type);
             }else{
                 this.connDetail(detailUrl,fileName);
             }
         }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
//解析原创书库详情页
private void connDetail(String detailUrl, String imageName,int type) {
    String channelId="";//栏目id
    String title="";//题名
    String author="";//作者
    String press="";//出版社
    String classification="";//分类
    String keyWords="";//关键词
    String ab="";//简介
    Document document=null;
    try {
        channelId=detailUrl.substring(detailUrl.lastIndexOf("/")+1, detailUrl.lastIndexOf("."));
        document=Jsoup.connect(detailUrl).cookies(cookies).timeout(60 * 1000).ignoreContentType(true).maxBodySize(10 * 1024 * 1024).get();
        Elements elements=document.select(".Bdescript2").eq(0);
        document.select(".Bdescript2").eq(0).select("h2").eq(0).text();
        title=elements.select("h2").eq(0).text();
        Elements tab=elements.select("table>tbody>tr>td");
        author=tab.eq(0).select("a").text();
        press=tab.eq(2).select("a").text();
        //classification=tab.eq(4).select("a").text();
        keyWords=tab.eq(7).select("a").text();
        ab=document.select(".paddbot").text();
        //读取一条存入数据库一条
        Elements eleChapter=document.select("#chapters_div");
        //存入数据库操作
        WriteToDateBase.insertChannel(channelId,title,author,press,classification,keyWords,ab,imageName);
        //有章节是
        if(!eleChapter.select("dd").isEmpty()){
            //存入一个数据库
            this.chapterDetail(eleChapter,channelId);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
//解析详情页
private void connDetail(String detailUrl,String imageName) {
    String channelId="";//栏目id
    String title="";//题名
    String author="";//作者
    String press="";//出版社
    String classification="";//分类
    String keyWords="";//关键词
    String ab="";//简介
    Document document=null;
    try {
        channelId=detailUrl.substring(detailUrl.lastIndexOf("/")+1, detailUrl.lastIndexOf("."));
        document=Jsoup.connect(detailUrl).cookies(cookies).timeout(60 * 1000).ignoreContentType(true).maxBodySize(10 * 1024 * 1024).get();
        Elements elements=document.select(".Bdescript").eq(0);
        document.select(".Bdescript").eq(0).select("h2").eq(0).text();
        title=elements.select("h2").eq(0).text();
        Elements tab=elements.select("table>tbody>tr>td");
        author=tab.eq(0).select("a").text();
        press=tab.eq(1).select("a").text();
        classification=tab.eq(4).select("a").text();
        keyWords=tab.eq(8).select("a").text();
        ab=elements.select("p").last().text();
        //读取一条存入数据库一条
        Elements eleChapter=document.select("#chapters_div");
        //存入数据库操作
        WriteToDateBase.insertChannel(channelId,title,author,press,classification,keyWords,ab,imageName);
        //有章节是
        if(!eleChapter.select("dd").isEmpty()){
            //存入一个数据库
            this.chapterDetail(eleChapter,channelId);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

}
/**
 * 读取没一章节的详细内容
 * @param eleChapter
 * @param channelId
 */
private void chapterDetail(Elements eleChapter, String channelId) {
    String urlIFeng="http://v.yc.ifeng.com";//进入凤凰网址url
    String typeAB="";//分类型章节
    String chapter="";//章节
    String chapterId="";//章节id
    String chapterContent="";//章节内容
    Elements elements=eleChapter.select("dd");
    for(int i=0;i<elements.size();i++){
        Element element=elements.get(i);
        typeAB=element.select("h5").text();
        Elements elemeA=element.select("a");
        for(int j=0;j<elemeA.size();j++){
            //获取href的最后一个数字
            String href=elemeA.get(j).attr("href");
            chapter=elemeA.get(j).text();
            String c=href.substring(href.lastIndexOf("/")+1,href.lastIndexOf("."));
            chapterId=c;
            String b=channelId;
            chapterContent=this.jsoupHTML(c,b);
            //存入数据库
            WriteToDateBase.insertContent(channelId,chapterId,typeAB,chapter,chapterContent);
        }

    }

}
//存入文件获取文件名称,存图片
public String saveImage(String imgUrl,String imagePath) throws IOException{
    // 构造URL  
    URL url = new URL(imgUrl);
    String filename=imgUrl.substring(imgUrl.lastIndexOf("/")+1,imgUrl.length());
    // 打开连接  
    URLConnection con=null;
    InputStream is=null;
    try {
         con = url.openConnection();  
        //设置请求超时为5s  
        con.setConnectTimeout(5*1000);  
        // 输入流  
        is = con.getInputStream(); 
    } catch (Exception e) {
        //图片不存在时,调用默认图片
        con =new URL("http://res.read.ifeng.com/images/book/book.jpg").openConnection();
        con.setConnectTimeout(5*1000);  
        is = con.getInputStream();  
    }
    // 1K的数据缓冲  
    byte[] bs = new byte[1024];  
    // 读取到的数据长度  
    int len;  
    // 输出的文件流  
   File sf=new File(imagePath);  
   if(!sf.exists()){  
       sf.mkdirs();  
   }  
   OutputStream os = new FileOutputStream(sf.getPath()+"\\"+filename);
    // 开始读取  
    while ((len = is.read(bs)) != -1) {  
      os.write(bs, 0, len);  
    }  
    // 完毕,关闭所有链接  
    os.close();  
    is.close();
    return filename;
}   
}

Elements这个对象提供了一系列类似于DOM的方法来查找元素,抽取并处理其中的数据。具体如下:
查找元素
getElementById(String id)
getElementsByTag(String tag)
getElementsByClass(String className)
getElementsByAttribute(String key) (and related methods)
Element siblings: siblingElements(), firstElementSibling(), lastElementSibling();nextElementSibling(), previousElementSibling()
Graph: parent(), children(), child(int index)
元素数据
attr(String key)获取属性attr(String key, String value)设置属性
attributes()获取所有属性
id(), className() and classNames()
text()获取文本内容text(String value) 设置文本内容
html()获取元素内HTMLhtml(String value)设置元素内的HTML内容
outerHtml()获取元素外HTML内容
data()获取数据内容(例如:script和style标签)
tag() and tagName()
操作HTML和文本
append(String html), prepend(String html)
appendText(String text), prependText(String text)
appendElement(String tagName), prependElement(String tagName)
html(String value)

Selector选择器概述
tagname: 通过标签查找元素,比如:a
ns|tag: 通过标签在命名空间查找元素,比如:可以用 fb|name 语法来查找 元素

id: 通过ID查找元素

.class: 通过class名称查找元素,比如:.masthead

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值