使用jsoup采集网页实例

来源:互联网 发布:大数据系统架构图 编辑:程序博客网 时间:2024/05/16 04:38

使用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

0 0
原创粉丝点击