网络爬虫之Spider

网络爬虫是搜索引擎的一个重要的部分。爬虫的根本原理就是下载页面,然后进行解析。Web上的存储着海量数据,怎么样才能将海量数据尽快的下载到本机上?这是网络爬虫设计的一个方案。采取多线程技术。以下代码实现了将网页的数据存储到XML文档。希望能提出更好的方案。

 

[java]  view plain copy
  1. import java.awt.*;  
  2.   
  3. import java.awt.event.*;  
  4.   
  5. import javax.swing.*;  
  6.   
  7. import java.util.*;  
  8.   
  9. import java.io.*;  
  10.   
  11.   
  12.   
  13. import com.heaton.bot.*;  
  14.   
  15.   
  16.   
  17. import org.w3c.dom.*;  
  18.   
  19. import org.cyberneko.html.parsers.*;  
  20.   
  21. import org.xml.sax.*;  
  22.   
  23. import org.apache.html.dom.*;  
  24.   
  25. import javax.xml.parsers.*;  
  26.   
  27. import javax.xml.transform.*;  
  28.   
  29. import javax.xml.transform.dom.*;  
  30.   
  31. import javax.xml.transform.stream.*;  
  32.   
  33.   
  34.   
  35. /** 
  36.  
  37. *  网络爬虫,通过深度优先算法将互联网上的网页下载解析。经过测试,能正常运行! 
  38.  
  39. */  
  40.   
  41. public class mySpider extends JFrame implements ISpiderReportable {  
  42.   
  43.   
  44.   
  45.     /** 
  46.  
  47.      * @param args 
  48.  
  49.      */  
  50.   
  51.     Spider _Spider = null;  
  52.   
  53.     Document doc = null;  
  54.   
  55.       
  56.   
  57.     int _pagesCount;  
  58.   
  59.       
  60.   
  61.     public mySpider(){  
  62.   
  63.         setTitle("网络爬虫之Spider");  
  64.   
  65.         getContentPane().setLayout(null);  
  66.   
  67.         setSize(405,268);  
  68.   
  69.         setVisible(false);  
  70.   
  71.         D.setHorizontalTextPosition(  
  72.   
  73.                 SwingConstants.LEFT);  
  74.   
  75.         D.setVerticalTextPosition(  
  76.   
  77.                 SwingConstants.TOP);  
  78.   
  79.         D.setVerticalAlignment(  
  80.   
  81.                 SwingConstants.TOP);  
  82.   
  83.         D.setText("下载的页面数目: ");  
  84.   
  85.         getContentPane().add(D);  
  86.   
  87.         D.setBounds(12,12,384,24);  
  88.   
  89.         JLabel2.setText("URL:");  
  90.   
  91.         getContentPane().add(JLabel2);  
  92.   
  93.         JLabel2.setBounds(12,36,36,24);  
  94.   
  95.         getContentPane().add(_url);  
  96.   
  97.         _url.setBounds(48,36,348,24);  
  98.   
  99.         JLabel3.setText("选择存储XML文档的目录:");  
  100.   
  101.         getContentPane().add(JLabel3);  
  102.   
  103.         JLabel3.setBounds(12,72,384,24);  
  104.   
  105.         getContentPane().add(_save);  
  106.   
  107.         _save.setBounds(12,96,384,24);  
  108.   
  109.         _go.setText("GO!");  
  110.   
  111.         getContentPane().add(_go);  
  112.   
  113.         _go.setBounds(96,228,216,24);  
  114.   
  115.         getContentPane().add(_current);  
  116.   
  117.         _current.setBounds(12,204,384,12);  
  118.   
  119.         JLabel4.setText("Number of pages:");  
  120.   
  121.         getContentPane().add(JLabel4);  
  122.   
  123.         JLabel4.setBounds(12,180,120,12);  
  124.   
  125.         _pages.setText("0");  
  126.   
  127.         getContentPane().add(_pages);  
  128.   
  129.         _pages.setBounds(120,180,108,12);  
  130.   
  131.         JLabel6.setText("选择Log,当前需要保存的日志:");  
  132.   
  133.         getContentPane().add(JLabel6);  
  134.   
  135.         JLabel6.setBounds(12,120,384,24);  
  136.   
  137.         _logPath.setText("./Spider.log");  
  138.   
  139.         getContentPane().add(_logPath);  
  140.   
  141.         _logPath.setBounds(12,144,384,24);  
  142.   
  143.         _go.setActionCommand("jbutton");  
  144.   
  145.           
  146.   
  147.         SymAction lSymAction = new SymAction();  
  148.   
  149.         _go.addActionListener(lSymAction);  
  150.   
  151.         SymWindow aSymWindow = new SymWindow();  
  152.   
  153.         this.addWindowListener(aSymWindow);  
  154.   
  155.           
  156.   
  157.         try{  
  158.   
  159.             DOMImplementation domImpl = DocumentBuilderFactory  
  160.   
  161.             .newInstance().newDocumentBuilder().getDOMImplementation();  
  162.   
  163.             doc = domImpl.createDocument(null,"spider",null);  
  164.   
  165.         }catch(ParserConfigurationException e){  
  166.   
  167.             e.printStackTrace();  
  168.   
  169.         }catch(DOMException e){  
  170.   
  171.             e.printStackTrace();  
  172.   
  173.         }  
  174.   
  175.     }  
  176.   
  177.       
  178.   
  179.     public void setVisible(boolean b){  
  180.   
  181.         if(b)  
  182.   
  183.             setLocation(50,50);  
  184.   
  185.         super.setVisible(b);  
  186.   
  187.     }  
  188.   
  189.       
  190.   
  191.     public static void main(String[] args) {  
  192.   
  193.         // TODO Auto-generated method stub  
  194.   
  195.         (new mySpider()).setVisible(true);  
  196.   
  197.     }  
  198.   
  199.       
  200.   
  201.     public void addNotify(){  
  202.   
  203.         Dimension size = getSize();  
  204.   
  205.           
  206.   
  207.         super.addNotify();  
  208.   
  209.           
  210.   
  211.         if(frameSizeAdjusted)  
  212.   
  213.             return;  
  214.   
  215.         frameSizeAdjusted = true;  
  216.   
  217.           
  218.   
  219.         Insets insets = getInsets();  
  220.   
  221.         JMenuBar menuBar = getRootPane().getJMenuBar();  
  222.   
  223.         int menuBarHeight = 0;  
  224.   
  225.         if(menuBar!=null)  
  226.   
  227.             menuBarHeight = menuBar.getPreferredSize().height;  
  228.   
  229.         setSize(insets.left+  
  230.   
  231.                 insets.right+  
  232.   
  233.                 size.width,  
  234.   
  235.                 insets.top+  
  236.   
  237.                 insets.bottom+  
  238.   
  239.                 size.height+menuBarHeight);  
  240.   
  241.     }  
  242.   
  243.   
  244.   
  245.     boolean frameSizeAdjusted = false;  
  246.   
  247.       
  248.   
  249.     JLabel D = new JLabel();  
  250.   
  251.     JLabel JLabel2 = new JLabel();  
  252.   
  253.       
  254.   
  255.     JTextField _url = new JTextField();  
  256.   
  257.     JLabel JLabel3 = new JLabel();  
  258.   
  259.       
  260.   
  261.     JTextField _save = new JTextField();  
  262.   
  263.     JButton _go = new JButton();  
  264.   
  265.       
  266.   
  267.     JLabel _current = new JLabel();  
  268.   
  269.     JLabel JLabel4 = new JLabel();  
  270.   
  271.       
  272.   
  273.     JLabel _pages = new JLabel();  
  274.   
  275.     JLabel JLabel6 = new JLabel();  
  276.   
  277.       
  278.   
  279.     JTextField _logPath = new JTextField();  
  280.   
  281.       
  282.   
  283.     class SymAction implements ActionListener{  
  284.   
  285.         public void actionPerformed(ActionEvent event){  
  286.   
  287.             Object object = event.getSource();  
  288.   
  289.             if(object == _go)  
  290.   
  291.                 Go_actionPerformed(event);  
  292.   
  293.         }  
  294.   
  295.     }  
  296.   
  297.       
  298.   
  299.     protected void processFile(HTTP file){  
  300.   
  301.         try{      
  302.   
  303.             if(_save.getText().length()>0){  
  304.   
  305.                 int i=file.getURL().lastIndexOf('/');  
  306.   
  307.                   
  308.   
  309.                 if(i!=-1){  
  310.   
  311.                     int iPoint = file.getURL().lastIndexOf('.');  
  312.   
  313.                     String extendName = file.getURL().substring(iPoint+1);  
  314.   
  315.                     if(extendName.equals("html") || extendName.equals("htm") || extendName.equals("shtml")){  
  316.   
  317.                         String fileBody = new String(file.getBody().getBytes("iso-8859-1"),"GBK");  
  318.   
  319.   
  320.   
  321.                         DOMFragmentParser parser = new DOMFragmentParser();  
  322.   
  323.                         DocumentFragment node =  
  324.   
  325.                               new HTMLDocumentImpl().createDocumentFragment();  
  326.   
  327.                         try {  
  328.   
  329.                             parser.setProperty("http://cyberneko.org/html/properties/default-encoding","GBK");  
  330.   
  331.                             parser.parse(new InputSource(new ByteArrayInputStream(fileBody.getBytes())), node);  
  332.   
  333.                         }catch (IOException e) {  
  334.   
  335.                             e.printStackTrace();  
  336.   
  337.                               
  338.   
  339.                         }catch (SAXException e) {  
  340.   
  341.                             e.printStackTrace();  
  342.   
  343.                               
  344.   
  345.                         }  
  346.   
  347.                           
  348.   
  349.                         StringBuffer sb = new StringBuffer();  
  350.   
  351.                         getText(sb, node, "title");  
  352.   
  353.                         String title = sb.toString();  
  354.   
  355.   
  356.   
  357.                         sb.setLength(0);  
  358.   
  359.                         getText(sb, node,"body");  
  360.   
  361.                         String text = sb.toString();  
  362.   
  363.                         text = text.replaceAll("<","<")  
  364.   
  365.                         .replaceAll(">",">");  
  366.   
  367.                         if(title.length()!=0 && text.length()!=0)  
  368.   
  369.                             addElementNode(doc,title,text,file.getURL());   
  370.   
  371.                     }  
  372.   
  373.                 }  
  374.   
  375.             }  
  376.   
  377.               
  378.   
  379.         }catch(Exception e){  
  380.   
  381.             Log.logException("Can't save output file: ",e);  
  382.   
  383.         }  
  384.   
  385.     }  
  386.   
  387.       
  388.   
  389.     private Element createTitleElement(Document docs,String title){  
  390.   
  391.         Element titleElement = docs.createElement("TITLE");  
  392.   
  393.         titleElement.setTextContent(title);  
  394.   
  395.         return titleElement;  
  396.   
  397.     }  
  398.   
  399.       
  400.   
  401.     private Element createBodyElement(Document docs,String body){  
  402.   
  403.         Element bodyElement = docs.createElement("BODY");  
  404.   
  405.         bodyElement.setTextContent(body);  
  406.   
  407.         return bodyElement;  
  408.   
  409.     }  
  410.   
  411.       
  412.   
  413.     private Element createURLElement(Document docs,String URL){  
  414.   
  415.         Element URLElement = docs.createElement("URL");  
  416.   
  417.         URLElement.setTextContent(URL);  
  418.   
  419.         return URLElement;  
  420.   
  421.     }  
  422.   
  423.       
  424.   
  425.     public void addElementNode(Document docs,String title,String body,String URL){  
  426.   
  427.         Element HTMLElement = docs.createElement("HTMLPAPER");  
  428.   
  429.           
  430.   
  431.         HTMLElement.appendChild(createTitleElement(docs,title));  
  432.   
  433.         HTMLElement.appendChild(createBodyElement(docs,body));  
  434.   
  435.         HTMLElement.appendChild(createURLElement(docs,URL));  
  436.   
  437.           
  438.   
  439.         docs.getDocumentElement().appendChild(HTMLElement);  
  440.   
  441.     }  
  442.   
  443.       
  444.   
  445.     private void getText(StringBuffer sb, Node node) {  
  446.   
  447.         if (node.getNodeType() == Node.TEXT_NODE) {  
  448.   
  449.           sb.append(node.getNodeValue());  
  450.   
  451.         }  
  452.   
  453.         NodeList children = node.getChildNodes();  
  454.   
  455.         if (children != null) {  
  456.   
  457.           int len = children.getLength();  
  458.   
  459.           for (int i = 0; i < len; i++) {  
  460.   
  461.             getText(sb, children.item(i));  
  462.   
  463.           }  
  464.   
  465.         }  
  466.   
  467.       }  
  468.   
  469.   
  470.   
  471.       private boolean getText(StringBuffer sb, Node node,  
  472.   
  473.         String element) {  
  474.   
  475.         if (node.getNodeType() == Node.ELEMENT_NODE) {  
  476.   
  477.           if (element.equalsIgnoreCase(node.getNodeName())) {  
  478.   
  479.             getText(sb, node);  
  480.   
  481.           }  
  482.   
  483.         }  
  484.   
  485.         NodeList children = node.getChildNodes();  
  486.   
  487.         if (children != null) {  
  488.   
  489.           int len = children.getLength();  
  490.   
  491.           for (int i = 0; i < len; i++) {  
  492.   
  493.             if (getText(sb, children.item(i), element)) {  
  494.   
  495.               return true;  
  496.   
  497.             }  
  498.   
  499.           }  
  500.   
  501.         }  
  502.   
  503.         return false;  
  504.   
  505.       }  
  506.   
  507.       
  508.   
  509.     void Go_actionPerformed(ActionEvent event){  
  510.   
  511.         IWorkloadStorable wl = new SpiderInternalWorkload();  
  512.   
  513.         if(_Spider!=null){  
  514.   
  515.             Runnable doLater = new Runnable(){  
  516.   
  517.                 public void run(){  
  518.   
  519.                     _go.setText("Canceling...");  
  520.   
  521.                 }  
  522.   
  523.             };  
  524.   
  525.             SwingUtilities.invokeLater(doLater);  
  526.   
  527.             _Spider.halt();  
  528.   
  529.             return;  
  530.   
  531.         }  
  532.   
  533.           
  534.   
  535.         try{  
  536.   
  537.             if(_url.getText().length()>0){  
  538.   
  539.                 HTTPSocket http = new HTTPSocket();  
  540.   
  541.                 http.send(_url.getText(),null);  
  542.   
  543.             }else{  
  544.   
  545.                 _current.setText("<<distributed mode>>");  
  546.   
  547.             }  
  548.   
  549.         }catch(Exception e){  
  550.   
  551.             JOptionPane.showMessageDialog(this,e,"Error",JOptionPane.OK_CANCEL_OPTION,null);  
  552.   
  553.             return;  
  554.   
  555.         }  
  556.   
  557.           
  558.   
  559.         Runnable doLater = new Runnable(){  
  560.   
  561.             public void run(){  
  562.   
  563.                 _go.setText("Cancel");  
  564.   
  565.                 _current.setText("Loading...");  
  566.   
  567.             }  
  568.   
  569.         };  
  570.   
  571.           
  572.   
  573.         SwingUtilities.invokeLater(doLater);  
  574.   
  575.         _pagesCount = 0;  
  576.   
  577.         if(_logPath.getText().length()>0){  
  578.   
  579.             File file = new File(_logPath.getText());  
  580.   
  581.             file.delete();  
  582.   
  583.             Log.setLevel(Log.LOG_LEVEL_NORMAL);  
  584.   
  585.             Log.setFile(true);  
  586.   
  587.             Log.setConsole(false);  
  588.   
  589.             Log.setPath(_logPath.getText());  
  590.   
  591.         }  
  592.   
  593.           
  594.   
  595.         try{  
  596.   
  597.             wl = new SpiderSQLWorkload(  
  598.   
  599.                     "sun.jdbc.odbc.JdbcOdbcDriver",  
  600.   
  601.                     "jdbc:odbc:WORKLOAD");  
  602.   
  603.         }catch(Exception e){  
  604.   
  605.             JOptionPane.showMessageDialog(this,  
  606.   
  607.                     e,  
  608.   
  609.                     "Error",  
  610.   
  611.                     JOptionPane.OK_CANCEL_OPTION,  
  612.   
  613.                     null);  
  614.   
  615.         }  
  616.   
  617.           
  618.   
  619.         _Spider = new Spider(this,  
  620.   
  621.                 _url.getText(),  
  622.   
  623.                 new HTTPSocket(),  
  624.   
  625.                 100,  
  626.   
  627.                 wl);  
  628.   
  629.         _Spider.setMaxBody(200);  
  630.   
  631.         _Spider.start();  
  632.   
  633.     }  
  634.   
  635.       
  636.   
  637.     public boolean foundInternalLink(String url){  
  638.   
  639.         return true;  
  640.   
  641.     }  
  642.   
  643.       
  644.   
  645.     public boolean foundExternalLink(String url){  
  646.   
  647.         return false;  
  648.   
  649.     }  
  650.   
  651.       
  652.   
  653.     public boolean foundOtherLink(String url){  
  654.   
  655.         return false;  
  656.   
  657.     }  
  658.   
  659.       
  660.   
  661.     class UpdateTarget implements Runnable{  
  662.   
  663.         public String _t;  
  664.   
  665.         public void run(){  
  666.   
  667.             _current.setText(_t);  
  668.   
  669.             _pages.setText(""+_pagesCount);  
  670.   
  671.         }  
  672.   
  673.     }  
  674.   
  675.       
  676.   
  677.     public void processPage(HTTP page){  
  678.   
  679.         _pagesCount++;  
  680.   
  681.         UpdateTarget ut = new UpdateTarget();  
  682.   
  683.         ut._t = page.getURL();  
  684.   
  685.         SwingUtilities.invokeLater(ut);  
  686.   
  687.         processFile(page);  
  688.   
  689.     }  
  690.   
  691.       
  692.   
  693.     public void completePage(HTTP page, boolean error){  
  694.   
  695.           
  696.   
  697.     }  
  698.   
  699.       
  700.   
  701.     public boolean getRemoveQuery(){  
  702.   
  703.         return true;  
  704.   
  705.     }  
  706.   
  707.       
  708.   
  709.     public void spiderComplete(){  
  710.   
  711.         if(_Spider.isHalted()){  
  712.   
  713.             JOptionPane.showMessageDialog(this,  
  714.   
  715.                     "下载正在被取消...... "+  
  716.   
  717.                     "请检查日志的错误!.",  
  718.   
  719.                     "完成下载!",  
  720.   
  721.                     JOptionPane.OK_CANCEL_OPTION,  
  722.   
  723.                     null);  
  724.   
  725.         }else{  
  726.   
  727.             JOptionPane.showMessageDialog(this,  
  728.   
  729.                     "下载完成..... "+  
  730.   
  731.                     "请检查日志的错误!.",  
  732.   
  733.                     "完成下载!",  
  734.   
  735.                     JOptionPane.OK_CANCEL_OPTION,  
  736.   
  737.                     null);        
  738.   
  739.         }  
  740.   
  741.           
  742.   
  743.         DOMSource doms = new DOMSource(doc);  
  744.   
  745.         File f = new File(_save.getText(),"HTMLPraser.xml");  
  746.   
  747.         StreamResult sr = new StreamResult(f);  
  748.   
  749.           
  750.   
  751.         try{  
  752.   
  753.             TransformerFactory tf = TransformerFactory.newInstance();  
  754.   
  755.             Transformer t = tf.newTransformer();  
  756.   
  757.               
  758.   
  759.             Properties properties = t.getOutputProperties();  
  760.   
  761.             properties.setProperty(OutputKeys.ENCODING,"GBK");  
  762.   
  763.             properties.setProperty(OutputKeys.INDENT,"yes");  
  764.   
  765.               
  766.   
  767.             t.setOutputProperties(properties);  
  768.   
  769.             t.transform(doms,sr);  
  770.   
  771.         }catch(TransformerConfigurationException tce){  
  772.   
  773.             tce.printStackTrace();  
  774.   
  775.         }catch(TransformerException te){  
  776.   
  777.             System.out.println("转换错误..../n-------");  
  778.   
  779.             te.printStackTrace();  
  780.   
  781.         }  
  782.   
  783.           
  784.   
  785.         _Spider = null;  
  786.   
  787.         Runnable doLater = new Runnable(){  
  788.   
  789.             public void run(){  
  790.   
  791.                 _go.setText("GO!!");  
  792.   
  793.             }  
  794.   
  795.         };  
  796.   
  797.         SwingUtilities.invokeLater(doLater);  
  798.   
  799.     }  
  800.   
  801.       
  802.   
  803.     class SymWindow extends WindowAdapter{  
  804.   
  805.         public void windowClosed(WindowEvent event){  
  806.   
  807.             Object object = event.getSource();  
  808.   
  809.             if(object==mySpider.this)  
  810.   
  811.                 GetSite_windowClosed(event);  
  812.   
  813.         }  
  814.   
  815.     }  
  816.   
  817.       
  818.   
  819.     void GetSite_windowClosed(WindowEvent event){  
  820.   
  821.         System.exit(0);  
  822.   
  823.     }  
  824.   
  825. }  
[java]  view plain copy
  1. <font color="#000000">以上是网络爬虫的代码。需要导入第三方包,可以在Eclipse环境下开发。但是本人</font>  
[java]  view plain copy
  1. <font color="#000000">配置环境变量,直接在记事本中开发。第三方包可以在网上下载。也可以向我索取。</font>  
[java]  view plain copy
  1. <font color="#000000">留下个人E-mail即可。</font>  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值