前一陣子在code 板上看見一個case,
那個case要求要 無名小站 的有效帳號350萬個,
感覺蠻有趣的,所以就寫了一隻小程式來抓看看Pixnet的帳號,
一開始還以為一直連server連太快會被擋掉,
但是後來完全不設延遲也不會被server檔掉,
頂多自己電腦變慢一點而已,
在測試這支程式時,還發生了蠻好玩的事情,
原本想在上課讓他跑一下,看看可以抓多少數量
但似乎是我流量太大,導致旁邊的同學無線網路都連不上
在我開始跑程式之前,其實他們是可以連線的,
不知道的學弟看到只有我能上網,只能很無奈的問我是不是我筆電比較大台比較厲害...
我也不敢說其實是我問題...
---------------------------------------------------------------------------------------------------
接下來說說我如何抓取帳號,
因為html,php,javascript這三個我都只是了解一點點,
所以我抓取帳號的方法很普通,只是根據html裡面每一行程式碼做比對
比對到我要的格式就記錄下來,比對的方式是用Regular Expression
之前看書常看到Regular Expression,這次終於用到....
比對的格式就是抓取文章中迴響人的帳號,
然後為了要讓他可以繼續搜尋其他blog,
我會將蒐尋到的帳號加入到等下要繼續搜尋的Arraylist裡面,
如此一來,就可以一直探索下去,
根據我的實驗,我放著給他跑一個晚上,早上起床也還沒停止
不過這樣找尋的辦法不是很有效率,
之後有機會再來研究有沒有更好的搜尋方法,
最後說明一下程式裡面幾個重要的設定:
all.txt
這文件檔是儲存所有帳號的地方,在重新要跑程式的時候,先把已有的帳號匯入,避免找到重複的,如果一開始沒有帳號,也要創一個空的
MAX_FILE
為要輸出檔案個個數 (分成很多檔是怕有意外的錯誤,導至跑很久的程式資料都沒存到
FILE_NUM
為每一份檔案儲存帳號的個數
post.add(http://admin.pixnet.net/blog);
這行表示一開始進去的搜尋網頁,每次重新搜尋可以找不同的熱門blog,不然只會重複搜尋,浪費時間
1: import java.io.BufferedReader;
2: import java.io.File;
3: import java.io.FileReader;
4: import java.io.FileWriter;
5: import java.io.IOException;
6: import java.io.InputStreamReader;
7: import java.net.MalformedURLException;
8: import java.net.URISyntaxException;
9: import java.net.URL;
10: import java.util.ArrayList;
11: import java.util.List;
12: import java.util.regex.Matcher;
13: import java.util.regex.Pattern;
14: public class trace {
15: public static void main( String args[] ) throws URISyntaxException, InterruptedException{
16: List<String> post = new ArrayList<String>();
17: List<String> user = new ArrayList<String>();
18:
19: /*user name; post; category;的RE*/
20: String patternUser = "[\\w]*\\.pixnet\\.net/blog";
21: String patternCategory = "http://[\\w]*\\.pixnet.net/blog/category/[\\w]*";
22: String patternPost = "http://[\\w]*\\.pixnet.net/blog/post/[\\w]*";
23:
24: String tmp;//暫存html字串
25:
26: Pattern User = Pattern.compile(patternUser);
27: Pattern Category = Pattern.compile(patternCategory);
28: Pattern Post = Pattern.compile(patternPost);
29:
30: Matcher matcherUser = null;
31: Matcher matcherCategory = null;
32: Matcher matcherPost = null;
33:
34: boolean UserFound;
35: boolean CategoryFound;
36: boolean PostFound;
37:
38: URL srcUrl = null;
39: BufferedReader in = null;
40: File saveFile = null;
41: FileWriter fwriter = null;
42:
43: int MAX_FILE = 100; //最大輸出檔案個數
44: int FILE_NUM = 100; //每一檔案儲存帳號個數
45: int txtNum = 0; //輸出檔案編號
46: int userNum = 0; //紀錄已輸出帳號個數
47: int initNum = 0; //紀錄all.txt中帳號個數
48:
49: //初始查詢的Blog
50: post.add("http://admin.pixnet.net/blog");
51:
52: loaduser(user); //讀入all.txt帳號
53: userNum=user.size();//初始帳號個數
54: initNum=user.size();//初始all.txt帳號個數
55:
56: while(txtNum < MAX_FILE)
57: {
58: //取得搜尋網頁網址
59: try {
60: srcUrl = new URL(post.get(0));
61: System.out.println( post.get(0) );
62: } catch (MalformedURLException e1) {
63: e1.printStackTrace();
64: }
65:
66: //開啟讀檔
67: try {
68: in = new BufferedReader( new InputStreamReader( srcUrl.openStream() ) );
69: saveFile = new File("UserName"+txtNum+".txt");//開啟存放會員名單
70: fwriter=new FileWriter(saveFile);//開啟寫檔
71: tmp = in.readLine();//讀下一行
72:
73: /*判斷post category user 找到就存下來*/
74: while( null != tmp ){
75: matcherUser = User.matcher(tmp);
76: matcherCategory = Category.matcher(tmp);
77: matcherPost = Post.matcher(tmp);
78:
79: UserFound = matcherUser.find();
80: CategoryFound = matcherCategory.find();
81: PostFound = matcherPost.find();
82:
83: //判斷是否比對成功
84: if(UserFound){
85: //儲存所有比對到的會員名稱
86: for(int i = 0; i <= matcherUser.groupCount(); i++) {
87: String userName = matcherUser.group(i); //第i筆
88: int dotNum = userName.indexOf("."); //找到第一個.的index
89: userName = userName.substring(0,dotNum);//取出會員名稱
90: if(!user.contains(userName)){
91: user.add(userName);
92: System.out.println( userName );
93: }
94: String blog = "http://"+userName+".pixnet.net/blog";
95: if(!post.contains(blog)){
96: post.add(blog);
97: }
98: }
99: }
100:
101: if(CategoryFound){
102: for(int i = 0; i <= matcherCategory.groupCount(); i++) {
103: String groupStr = matcherCategory.group(i);
104: if(!post.contains(groupStr))
105: post.add(groupStr);
106: }
107: }
108:
109: if(PostFound){
110: for(int i = 0; i <= matcherPost.groupCount(); i++) {
111: String groupStr = matcherPost.group(i);
112: if(!post.contains(groupStr))
113: post.add(groupStr);
114: }
115: }
116:
117: tmp = in.readLine();//讀下一行
118: }
119: } catch (IOException e1) {
120: post.remove(0); //發生例外事件直接讀取下一個網址
121: continue;
122: }
123:
124: post.remove(0);//刪除目前網址
125:
126: //每FILE_NUM個數輸出檔案
127: if((user.size()-initNum)/FILE_NUM > txtNum)
128: {
129: for(int i=userNum;i<user.size();i++)
130: {
131: try{
132: fwriter.write(user.get(i)+"\n");
133: }
134: catch(Exception e){
135: e.printStackTrace();
136: }
137: }
138: userNum=user.size();
139: txtNum++;
140: try {
141: fwriter.close();
142: } catch (IOException e) {
143: e.printStackTrace();
144: }
145: }
146: }
147:
148: try {
149: in.close();
150: } catch (IOException e) {
151: e.printStackTrace();
152: }
153: }
154:
155:
156: //讀入已儲存user資料
157: public static void loaduser(List<String> user)
158: {
159: try {
160: BufferedReader buffer = new BufferedReader( new FileReader( "all.txt" ));
161: String line = buffer.readLine();
162:
163: while (line != null) {
164: user.add(line);
165: line = buffer.readLine();
166: }
167: buffer.close();
168: }
169: catch (IOException e) {
170: e.printStackTrace();
171: }
172: }
173: }
174:
留言列表