2014-07-17 71 views
0

我几个月来一直在使用crawler4j。我最近开始注意到它挂在一些网站上永远不会返回。推荐的解决方案是设置可恢复为真。这对我来说不是一种选择,因为我在空间上受到限制。我跑了多个测试,并注意到挂起非常随机。它将在90-140个网址之间爬行,然后停止。我想也许这是该网站,但在网站robot.txt中没有任何可疑内容,所有页面都以200 OK响应。我知道抓取工具没有抓取整个网站,否则它会关闭。有什么可能导致这种情况,我应该从哪里开始?为什么crawler4j会随机挂起?

什么有趣的是,我开始检索器非阻塞,是一个while循环检查状态后

controller.startNonBlocking(CrawlProcess.class, numberOfCrawlers); 

while(true){ 
    System.out.println("While looping"); 
} 
当履带挂while循环也停止响应,但线程还活着

。这意味着整个线程没有响应。因此,我无法发送关机命令。

UPDATE 我想清楚是什么导致它挂起。我在访问方法中使用mysql步骤运行商店。步骤如下:

public void insertToTable(String dbTable, String url2, String cleanFileName, String dmn, String AID, 
     String TID, String LID, String att, String ttl, String type, String lbl, String QL, 
     String referrer, String DID, String fp_type, String ipAddress, String aT, String sNmbr) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException{ 
    try{ 
     String strdmn = ""; 
     if(dmn.contains("www")){ 
      strdmn = dmn.replace("http://www.",""); 
     }else{ 
      strdmn = dmn.replace("http://",""); 
     } 
     String query = "INSERT INTO "+dbTable 
       +" (url,filename, dmn, AID, TID, LID, att, ttl, type, lbl, tracklist, referrer, DID, searchtype, description, fp_type, ipaddress," + 
       " aT, sNmbr, URL_Hash, iteration)VALUES('" 
       +url2+"','"+cleanFileName+"','"+strdmn+"','"+AID+"','"+TID+"','"+LID+"','"+att+"','"+ttl+"','"+type+"'" + 
       ",'"+lbl+"','"+QL+"','"+dmn+"','"+DID+"','spider','"+cleanFileName+"','"+fp_type+"'," + 
       "'"+ipAddress+"','"+aT+"','"+sNmbr+"',MD5('"+url2+"'), 1) ON DUPLICATE KEY UPDATE iteration = iteration + 1"; 
     Statement st2 = null; 
     con = DbConfig.openCons(); 
     st2 = con.createStatement(); 
     st2.executeUpdate(query); 
     //st2.execute("SELECT NOW()"); 
     st2.close(); 
     con.close(); 
     if(con.isClosed()){ 
      System.out.println("CON is CLOSED"); 
     }else{ 
      System.out.println("CON is OPEN"); 
     } 
     if(st.isClosed()){ 
      System.out.println("ST is CLOSED"); 
     }else{ 
      System.out.println("ST is OPEN"); 
     } 
    }catch(NullPointerException npe){ 
     System.out.println("NPE: " + npe); 
    } 
} 

什么是非常有趣的是当我运行st2.execute(“SELECT NOW()”);而不是当前的st2.execute(查询);它可以正常工作,并且不会挂起网站。但由于某种原因,st2.execute(查询)导致它在几个查询后挂起。这不是mysql,因为它不输出任何异常。我想也许我会从mysql获得“太多连接”,但情况并非如此。我的过程对任何人都有意义吗?

+0

调试器或线程转储。 – djechlin

+0

除了eclipse,我可以使用什么来调试?我使用MAT来获得堆转储,但这并没有给我任何有用的东西。奇怪的是它并不适用于所有领域。对于某些域,它可以毫无问题地抓取整个网站。 – Andy

+1

线程转储将告诉你在crawler4j它挂在哪里。 – djechlin

回答

2

finally块的重要性。

crawler4j正在使用c3p0池来插入到mysql中。几次查询后,爬虫将停止响应。由于@ djechlin的建议,它变成了c3p0中的连接泄漏。我添加了一个像下面这样的finally块,现在它工作的很好!

try{ 
    //the insert method is here 
}catch(SQLException e){ 
    e.printStackTrace(); 
}finally{ 
    if(st != null){ 
    st.close(); 
    } 
    if(rs != null){ 
    rs.close(); 
    } 

}