关闭

利用jsoup爬虫优酷、土豆等视频网站rss利用solr创建索引

标签: solr数据爬虫
1427人阅读 评论(1) 收藏 举报
分类:

1、前提:

了解jsoup、solr等相关的技术、会搭建solr

2、我将爬虫的网站都写在一个xml中,所以先要解析这个xml,得到其网址,然后定时去爬虫

  1. package com.tmzs.pc.jsoup;  
  2.   
  3. import java.io.File;  
  4. import java.util.ArrayList;  
  5. import java.util.Iterator;  
  6. import java.util.List;  
  7. import java.util.Timer;  
  8.   
  9. import org.dom4j.Document;  
  10. import org.dom4j.Element;  
  11. import org.dom4j.io.SAXReader;  
  12.   
  13. import com.tmzs.pc.entity.InfoXml;  
  14. /** 
  15.  * @功能 定时器,定时的爬虫 
  16.  * @author admin 
  17.  * 
  18.  */  
  19. public class TestTimer {  
  20.     public static final List<InfoXml> infoList = new ArrayList<InfoXml>() ;  
  21.     public static void main(String[] args) throws Exception {  
  22.         parseXml() ;  
  23.         MyTask myTask = new MyTask();  
  24.         Timer timer = new Timer();  
  25.         timer.schedule(myTask, 40001000*60*5);   //4000后执行,每次间隔1000*60*5=5分钟  
  26.     }  
  27.   
  28.     /** 
  29.      * @功能 解析XML 
  30.      * @throws Exception 
  31.      */  
  32.     private static void parseXml() throws Exception {  
  33.         SAXReader reader = new SAXReader();    
  34.         Document  document = reader.read(new File("e:/Channel.xml"));    
  35.         Element root = document.getRootElement();  //获取根节点  
  36.         List<Element> nodes = root.elements("tree");    
  37.           
  38.         for (Iterator it = nodes.iterator(); it.hasNext();) {    
  39.             Element tree = (Element) it.next();    
  40.             List<Element> channels = tree.elements("channel");    
  41.               
  42.             //Channel  
  43.             for (Iterator ite = channels.iterator(); ite.hasNext();) {    
  44.                 Element channel = (Element) ite.next();    
  45.                 InfoXml ix = new InfoXml() ;  
  46.                 ix.setTreeName(tree.attributeValue("name")) ;  
  47.                 ix.setTreeOpen(Integer.parseInt(tree.attributeValue("open"))) ;  
  48.                   
  49.                 ix.setChannelName(channel.element("name").getTextTrim()) ;  
  50.                 ix.setChannelLink(channel.element("link").getTextTrim()) ;  
  51.                 ix.setChannelType(channel.element("type").getTextTrim()) ;  
  52.                 ix.setChannelAllNewsNum(Integer.parseInt(channel.element("AllNewsNum").getTextTrim())) ;  
  53.                 ix.setChannelMaxNewsNum(Integer.parseInt(channel.element("MaxNewsNum").getTextTrim())) ;  
  54.                 ix.setChannelTTU(Integer.parseInt(channel.element("TTU").getTextTrim())) ;  
  55.                 ix.setChannelUnReadNewsNum(Integer.parseInt(channel.element("UnReadNewsNum").getTextTrim())) ;  
  56.                 infoList.add(ix) ;  
  57.             }   
  58.               
  59.         }   
  60.   
  61.         for(int i=0;i<infoList.size();i++){  
  62.             InfoXml ix = infoList.get(i) ;  
  63.             System.out.println("getTreeName="+ix.getTreeName()+",getChannelName="+ix.getChannelName()  
  64.                     +",channelType="+ix.getChannelType()+",link="+ix.getChannelLink());  
  65.         }  
  66.           
  67.     }  
  68. }  

3、执行定时器的方法,即爬虫。但是要考虑一个问题,爬虫的内容是否会重复。这里我是弄了连个Map,将爬虫的视频标题(title)放入Map里面作为Key。然后做了一个循环,当10次后爬虫的数据的title在Map里面没有,就清楚Map,说的不好,请看代码:

还有一点就是<link>标签得不到,所以我借助了rssjlib.jar

  1. package com.tmzs.pc.jsoup;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.io.StringReader;  
  8. import java.net.MalformedURLException;  
  9. import java.net.URL;  
  10. import java.net.URLConnection;  
  11. import java.text.ParseException;  
  12. import java.text.SimpleDateFormat;  
  13. import java.util.Date;  
  14. import java.util.HashMap;  
  15. import java.util.Iterator;  
  16. import java.util.List;  
  17. import java.util.Locale;  
  18. import java.util.Map;  
  19. import java.util.TimerTask;  
  20.   
  21. import org.apache.solr.client.solrj.impl.HttpSolrServer;  
  22. import org.apache.solr.common.SolrInputDocument;  
  23. import org.jsoup.Jsoup;  
  24. import org.jsoup.nodes.Document;  
  25. import org.jsoup.nodes.Element;  
  26. import org.jsoup.select.Elements;  
  27.   
  28. import com.rsslibj.elements.Channel;  
  29. import com.rsslibj.elements.Item;  
  30. import com.rsslibj.elements.RSSReader;  
  31. import com.tmzs.pc.entity.InfoXml;  
  32. import com.tmzs.pc.entity.Video;  
  33. import com.tmzs.pc.jdbc.JdbcAction;  
  34.   
  35. /** 
  36.  * @功能 爬虫 
  37.  * @author admin 
  38.  * 
  39.  */  
  40. public class MyTask extends TimerTask{  
  41.     /** 
  42.      * @功能 循环遍历XML 
  43.      */  
  44.     private static Channel channel;    //RSS实体    
  45.     Document doc = null;    
  46.     Map oldMap = new HashMap();       
  47.     Map newMap = new HashMap();   
  48.     int index = 1 ;  
  49.     int oldZeroNum = 0 ;  
  50.     boolean flag = true ;  
  51.     public void run(){  
  52.         List<InfoXml> urls = TestTimer.infoList ;  
  53.               
  54.         int zeroNum = 0 ;  
  55.         for(int j=0;j<urls.size();j++){  
  56.             InfoXml ix = urls.get(j) ;  
  57.             String url = ix.getChannelLink();    
  58.             URL ur;  
  59.             List<Item> items = null ;  
  60.             try {  
  61.                 ur = new URL(url);  
  62.                 InputStream inputstream = ur.openStream();    
  63.                 BufferedReader reader = null;    
  64.                 //由于百度编码不是UTF-8,所以你懂得  
  65.                 if("百度".equals(ix.getTreeName())){  
  66.                     flag = true ;  
  67.                     reader = new BufferedReader(new InputStreamReader(inputstream,"GB2312"));   
  68.                 }else{  
  69.                     flag = false ;  
  70.                     reader = new BufferedReader(new InputStreamReader(inputstream));   
  71.                 }  
  72.                 StringBuilder data = new StringBuilder();    
  73.                 String line = null;    
  74.                 while( (line = reader.readLine()) != null ) {    
  75.                     data.append(line);    
  76.                 }    
  77.                     
  78.                 reader.close();    
  79.                 inputstream.close();    
  80.                 //解析字符串    
  81.                 StringReader read = new StringReader(data.toString());    
  82.                 System.out.println("data.toString()="+data.toString());  
  83.                   
  84.                 doc = Jsoup.parse(data.toString());  
  85.                  
  86.                 // 创建RSS阅读对象的    
  87.                 RSSReader rssReader = new RSSReader();    
  88.                 // 设置读取内容    
  89.                 rssReader.setReader(read);  
  90.                     
  91.                 channel = rssReader.getChannel();   
  92.                 items = channel.getItems();  
  93.             } catch (MalformedURLException e1) {  
  94.                 e1.printStackTrace();  
  95.             } catch (IOException e) {  
  96.                 e.printStackTrace();  
  97.             } catch (electric.xml.ParseException e) {  
  98.                 e.printStackTrace();  
  99.             }    
  100.               
  101.             Elements element = doc.getElementsByTag("channel");  
  102.             Elements elems = doc.getElementsByTag("item");    
  103.             for(int i=0;i<elems.size();i++){  
  104.                 Item item = items.get(i) ;  
  105.                 Element elem = elems.get(i) ;  
  106.                 Elements title = elem.getElementsByTag("title") ;  
  107.                 if(index == 1){  
  108.                     oldMap.put(title.html(), 1) ;  
  109.                     //保存数据  
  110.                     insertData(element,elem,ix,channel,item) ;  
  111.                 }else if(index > 1){  
  112.                     if(oldMap.containsKey(title.html())){  
  113.                         zeroNum ++ ;  
  114.                     }else{  
  115.                         if(!newMap.containsKey(title.html())){  
  116.                             newMap.put(title.html(), 1) ;  
  117.                             insertData(element,elem,ix,channel,item) ;  
  118.                         }  
  119.                     }  
  120.                       
  121.                 }  
  122.             }  
  123.         }  
  124.         //判断是否清楚Map  
  125.         if(zeroNum == 0){  
  126.             oldZeroNum++;  
  127.             if(oldZeroNum == 10){  
  128.                 oldMap.clear();  
  129.                 oldZeroNum = 0;  
  130.                 oldMap = newMap;  
  131.                 newMap.clear();  
  132.             }  
  133.         }  
  134.         index++ ;  
  135.     }  
  136.       
  137.     /** 
  138.      * @功能 保存数据 
  139.      * @param element 
  140.      * @param elem 
  141.      */  
  142.     private void insertData(Elements element, Element elem, InfoXml ix,Channel channel,Item item) {  
  143.         String sourceLink = channel.getLink() ;  
  144.         String itemLink = item.getLink() ;  
  145.           
  146.         Elements sourceTitle = element.get(0).getElementsByTag("title") ;  
  147. //      Elements sourceLink = element.get(0).getElementsByTag("link") ;  
  148.         Elements sourceDesc = element.get(0).getElementsByTag("description") ;  
  149.         Elements sourceImageUrl = element.get(0).getElementsByTag("url") ;  
  150.          
  151.         Elements title = elem.getElementsByTag("title") ;  
  152.         Elements guid = elem.getElementsByTag("guid") ;  
  153.  //     Elements link = elem.getElementsByTag("link") ;  
  154.         Elements description = elem.getElementsByTag("description") ;  
  155.         Elements duration = elem.getElementsByTag("itunes:duration") ;  
  156.         Elements keyword = elem.getElementsByTag("itunes:keywords") ;  
  157.         Elements author = elem.getElementsByTag("author") ;  
  158.         Elements pubDate = elem.getElementsByTag("pubDate") ;  
  159.         Elements enclosure = elem.getElementsByTag("enclosure") ;  
  160.         Elements itemSource = elem.getElementsByTag("source") ;  //条目源,如:百度中新闻来自新闻网  
  161.         String itemFileType = enclosure.attr("type") ;  
  162.         String itemFileLink = enclosure.attr("url") ;  
  163.         SimpleDateFormat sf = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss z",Locale.ENGLISH);  
  164.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;  
  165.         String itemDate = "";  
  166.         try {  
  167.             if(!flag){  
  168.                 java.util.Date d = sf.parse(pubDate.html());  
  169.                 itemDate = sdf.format(d) ;  
  170.             }else{  
  171.                 itemDate = pubDate.html().replaceAll("T"" ").replaceAll(".000Z""") ;  
  172.             }  
  173.               
  174.         } catch (ParseException e) {  
  175.             e.printStackTrace();  
  176.         }  
  177.         int itemDuration = 0 ;  
  178.         if(!"".equals(duration.html())){  
  179.             itemDuration = parseDate(duration.html()) ;  
  180.         }  
  181.           
  182.         Video v = new Video() ;  
  183.         v.setId(new Date().getTime()+"") ;  
  184.         v.setTypeName(ix.getChannelType()) ;  
  185.         v.setClassName(ix.getTreeName()+"_"+ix.getChannelName()) ;  
  186.           
  187.         v.setSourceDesc(sourceDesc.first().html()) ;  
  188.         if(sourceImageUrl.first()!=null){  
  189.             v.setSourceImageLink(sourceImageUrl.first().html()) ;  
  190.         }else{  
  191.             v.setSourceImageLink("") ;  
  192.         }  
  193.         v.setSourceLink(sourceLink) ;  
  194.         v.setSourceTitle(sourceTitle.first().html()) ;  
  195.           
  196.         v.setItemDate(sdf.format(new Date())) ;             //solr处理时间  
  197.         v.setItemTitle(title.html()) ;  
  198.         v.setItemLink(itemLink) ;  
  199.           
  200.         v.setItemPubDate(itemDate) ;  
  201.           
  202.         v.setItemDesc(description.html()) ;  
  203.         v.setItemAuthor(author.html()) ;  
  204.         v.setItemSource(itemSource.html()) ;  //条目源,如:百度中新闻来自新闻网  
  205.         v.setItemKeyword(keyword.html()) ;  
  206.         v.setItemDuration(itemDuration) ;  
  207.         v.setItemGuid(guid.html()) ;  
  208.         v.setItemFileLink(itemFileLink) ;  
  209.         v.setItemFileType(itemFileType) ;  
  210.           
  211.         v.setState(400) ;  
  212.         writerSolr(v) ;  
  213. //      JdbcAction.insert(v) ;  
  214.     }  
  215.   
  216.     /** 
  217.      * @功能 写进索引 
  218.      */  
  219.     public void writerSolr(Video v) {  
  220.         // TODO Auto-generated method stub  
  221.          try {  
  222.               //获取连接服务  
  223.              HttpSolrServer solrServer= SolrServer.getInstance().getServer();  
  224.               SolrInputDocument doc1 = new SolrInputDocument();  
  225.               doc1.addField("id", v.getId());  
  226.               doc1.addField("typename", v.getTypeName());  
  227.               doc1.addField("classname", v.getClassName());  
  228.               doc1.addField("itemauthor", v.getItemAuthor());  
  229.               doc1.addField("itemdate", v.getItemDate());  
  230.               doc1.addField("itemdesc", v.getItemDesc());  
  231.               doc1.addField("itemduration", v.getItemDuration());  
  232.                 
  233.               doc1.addField("itemfilelink", v.getItemFileLink());  
  234.               doc1.addField("itemfiletype", v.getItemFileType());  
  235.               doc1.addField("itemguid", v.getItemGuid());  
  236.               doc1.addField("itemkeyword", v.getItemKeyword());  
  237.               doc1.addField("itemlink", v.getItemLink());  
  238.                 
  239.               doc1.addField("itempubdate", v.getItemPubDate());  
  240.               doc1.addField("itemsource", v.getItemSource());  
  241.               doc1.addField("itemtitle", v.getItemTitle());  
  242.               doc1.addField("sourcedesc", v.getSourceDesc());  
  243.               doc1.addField("sourceimagelink", v.getSourceImageLink());  
  244.               doc1.addField("sourcelink", v.getSourceLink());  
  245.               doc1.addField("sourcetitle", v.getSourceTitle());  
  246.                 
  247.               solrServer.add(doc1);  
  248.               solrServer.commit();  
  249.         } catch (Exception e) {  
  250.             e.printStackTrace();  
  251.         }  
  252.     }  
  253.       
  254.     /** 
  255.      * @功能 将形如XX:XX的时间转为秒数 
  256.      * @param html 
  257.      * @return 
  258.      */  
  259.     private static int parseDate(String duration) {  
  260.         int itemDuration = 0 ;  
  261.         SimpleDateFormat sdf = new SimpleDateFormat("mm:ss") ;  
  262.         try {  
  263.             Date d = sdf.parse(duration) ;  
  264.             itemDuration = d.getMinutes()*60+d.getSeconds() ;  
  265.         } catch (ParseException e) {  
  266.             e.printStackTrace();  
  267.         }  
  268.         return itemDuration;  
  269.     }  
  270.   
  271.     public static void main(String[] args) throws Exception {  
  272.         SimpleDateFormat sf = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss z",Locale.ENGLISH);  
  273.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;  
  274.         SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") ;  
  275.         String itemDate = "";  
  276.         try {  
  277.             java.util.Date d = sf.parse("Mon, 19 Mar 2012 10:36:17 +0800");  
  278.               
  279.             System.out.println(sd.parse("2013-12-04T08:08:45.000Z"));  
  280.             itemDate = sdf.format(d) ;  
  281.         } catch (ParseException e) {  
  282.             e.printStackTrace();  
  283.         }  
  284.         System.out.println(sdf.parse(itemDate));   
  285.     }  
  286. }  

4、爬完之后,在solr页面可以看到

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:247221次
    • 积分:4278
    • 等级:
    • 排名:第7078名
    • 原创:166篇
    • 转载:47篇
    • 译文:13篇
    • 评论:28条
    最新评论