Eu sempre quis praticar dados de dados de multi-thread Java.
Um dia, descobri que o site oficial do Rings Duoduo (http://www.shoujiduoduo.com/main/) possui uma grande quantidade de dados.
Observando seu Ajax front-end para obter dados de toque
http://www.shoujiduoduo.com/ringweb/ringweb.php?type=getList&listid= {Category Id} & Page = {Número da página da paginação}
É fácil descobrir que, alterando o listid e a página, você pode obter os dados JSON do toque do servidor e analisando os dados JSON,
Você pode ver que todos eles têm instruções como {"Hasmore": 1, "Curpage": 1}. Ao julgar o valor de Hasmore, decidimos se devemos rastrear a próxima página.
No entanto, o endereço de download em JSON retornou através do link acima sem toques não está disponível no JSON
Em breve, você descobrirá que o verá clicando no "Download" na página.
Através da solicitação a seguir, você pode obter o endereço de download do toque
http://www.shoujiduoduo.com/ringweb/ringweb.php?type=geturl&act=down&rid= (ringtone id}
Portanto, seus dados são facilmente roubados. Então eu comecei ...
O código -fonte foi publicado no GitHub. Se você estiver interessado no lugar infantil, verifique
Github: https://github.com/yongbo000/duoduoaudiorobot
No código:
pacote me.yongbo.duoduoringRobot; importar java.io.bufferedreader; importar java.io.file; importar java.io.filewriter; importar java.io.ioException; importação java.io.inputStream; import java.io.ininninn; java.util.iterator; importar java.util.regex.matcher; importar java.util.regex.pattern; importar com.google.gson.gson; import com.google.gson.jsonArray; import com.google.gson.jsonElement; import.GOOGL.GSONARY; 2013/4/16 * * */public classe duoduoringRobotClient implementa runnable {public static string get_ringinfo_url = "http://www.shoujiduoduo.com/ringweb/ringweb.phpage?type=getList&listIdntid=®15 Get_down_url = "http://www.shoujiduoduo.com/ringweb/ringweb.php?type=geturl&act=down&rid=%1$d") strat strat strat Error_msg =" um erro ocorreu com listid de %1 d e aTATUSTULT APLOTUGADO APLOTED APLOTED. "Inicie dados de rastejamento, listid atual: %1 $ d, página atual: %2 $ d"; public static string file_dir = "e:/ringdata/"; public static string file_name = "listid = %1 $ d.txt"; private boolean errorflag = false; Construtor* @param listId Menu ID* @param página número inicial número* @param endpage end página número**/public duoduoringRobotClient (int listId, int BeginPage, int endPage) {this.listId = listId; this.page = inginPage; this.endPage = endPage; this.dbHelperper; ListID ID do menu * @param página inicial número da página * */public duoduoringRobotClient (int listId, int página) {this (listId, página, -1);}/** * get ringtone * */public void getrings () {string url = string.format (get_ringinfo_url (listIDID); Gethasmore (ResponsEst); Page = getNextPage (ResponsEst); ringparse (Responsest.Replaceall ("// {/" hasmore/": [0-9]*,/" Curpage/": [0-9]* //},", ") .replaceall (",] ""]; endereço * */public string httpget (string weburl) {url url; urlConnection con; stringbuilder sb = new stringbuilder (); string restasttr = ""; try {url = newrl (weburl); conn = url.openconnection (); conn.connect (); emputStream); conexão = conexão. InputStreamReader (IS); BufferReader BUFReader = new BufferredReader (ISR); String lineText; while ((lineText = bufreader.readLine ())! = null) {sb.append (lineText);} Resultado = sb.toString ();} catch (exceção e) {errorflag = true; // escreva um erro para txtWritetofile (string.format (error_msg, listID; e salve -o em txt* @param json json string**/public void ringparse (string json) {anel anel = null; jsonElement element = new jsonparser (). (it.hasnext () &&! errorflag) {jsonElement e = it.Next (); // Converte jSonelement em javabean objeto anel = gson.fromjson (e, ring.class); ring.set.setDownurl (getringDowrl (ring.getId ()); se (isAVAlLaring) {System.out.println (ring.toString ()); // Você pode optar por escrever no banco de dados ou para textos // writEtofile (ring.toString ()); writeTodatabase (ring);}}}}/** * write to txt * @param string string */public writet writettille String.Format (FILE_NAME, LISTID); FILE Dir = new File (file_dir); arquivo file = new File (Path); FileWriter FW = NULL; if (! DIR.Exists ()) {Dir.mkdirs ();} tente {if (! File.exists ()) {file.creatEnewFile;}; true); fw.write (dados); fw.write ("/r/n"); fw.flush ();} catch (ioexception e) {// todo-gate-gat de gestão automática Blocke.printStackTrace ();} finalmente {tente {se (fw! = null) {fw.close (); Catch Blocke.printStackTrace ();}}/***, gerado automaticamente, escreva no banco de dados* @param anel uma instância de anel**/public void writeTodatabase (anel anel) {dbhelper.execute ("addring", has);} @sroidepublic dbrin () (run (hound); ! = -1) {if (Page> endpage) {break; }}System.out.println(String.format(STATUS_MSG, listId, page));getRings();System.out.println(String.format("The data written on this page is completed"));}System.out.println("ending...");}private int getHasmore(String resultStr){Pattern p = Pattern.compile ("/" Hasmore/": ([0-9]*),/" Curpage/": ([0-9]*)"); Matcher Match = P.Matcher (Resultado); if (match.find ()) {return Integer.parseint (match.group (1)); } return 0;} private int getNextPage (String Resultstr) {padrão p = padrony.compile ("/" hasmore/": ([0-9]*),/" Curpage/": ([0-9]*)"); Return; MatcherInTer = P.Matcher (Resultoustr); se (matt.Ind () {Return Integer.Per.Per.PeryMEINTEINTEINTENTE (RETURNIMEINTINTENTE.PROTHSEINTEINTEINTEIRTEMEINTE (Return); Determine se o anel atual atende à condição. Quando o nome do anel é superior a 50 caracteres ou a duração é decimal, ele não atende às condições e será removido. * @param anel de anel atual Instância do objeto do anel**/private boolean isavailablerening (anel anel) {padrão p = padrony.compile ("^[1-9] [0-9]* $"); matcher match = p.matcher (ring.getduration ()); if (! Match.find)) {return;} se (.getduration ()); if (! Match.find)) {Return;} se ((.getnAmation); ||.