java 抓取天涯帖子_Java简单的实现网络爬虫(转载)

最近在学习搜索方面的东西,需要了解网络爬虫方面的知识,虽然有很多开源的强大的爬虫,但本着学习的态度,自己写了一个简单的网络爬虫,以便了解其中原理。

首先介绍每个类的功能:

DownloadPage.java的功能是下载此超链接的页面源代码.

FunctionUtils.java 的功能是提供不同的静态方法,包括:页面链接正则表达式匹配,获取URL链接的元素,判断是否创建文件,获取页面的Url并将其转换为规范的Url,截取网页网页源文件的目标内容。

HrefOfPage.java 的功能是获取页面源代码的超链接。

UrlDataHanding.java 的功能是整合各个给类,实现url到获取数据到数据处理类。

UrlQueue.java 的未访问Url队列。

VisitedUrlQueue.java 已访问过的URL队列。

下面介绍一下每个类的源代码:

DownloadPage.java 此类要用到HttpClient组件。

1.View Code

2. package com.sreach.spider;

3.

4. import java.io.IOException;

5. import org.apache.http.HttpEntity;

6. import org.apache.http.HttpResponse;

7. import org.apache.http.client.ClientProtocolException;

8. import org.apache.http.client.HttpClient;

9. import org.apache.http.client.methods.HttpGet;

10. import org.apache.http.impl.client.DefaultHttpClient;

11. import org.apache.http.util.EntityUtils;

12.

13. public class DownloadPage

14. {

15.

16. /**

17. * 根据URL抓取网页内容

18. *

19. * @param url

20. * @return

21. */

22. public static String getContentFormUrl(String url)

23. {

24. /* 实例化一个HttpClient客户端 */

25. HttpClient client = new DefaultHttpClient();

26. HttpGet getHttp = new HttpGet(url);

27.

28. String content = null;

29.

30. HttpResponse response;

31. try

32. {

33. /*获得信息载体*/

34. response = client.execute(getHttp);

35. HttpEntity entity = response.getEntity();

36.

37. VisitedUrlQueue.addElem(url);

38.

39. if (entity != null)

40. {

41. /* 转化为文本信息 */

42. content = EntityUtils.toString(entity);

43.

44. /* 判断是否符合下载网页源代码到本地的条件 */

45. if (FunctionUtils.isCreateFile(url)

46. && FunctionUtils.isHasGoalContent(content) != -1)

47. {

48. FunctionUtils.createFile(FunctionUtils

49. .getGoalContent(content), url);

50. }

51. }

52.

53. } catch (ClientProtocolException e)

54. {

55. e.printStackTrace();

56. } catch (IOException e)

57. {

58. e.printStackTrace();

59. } finally

60. {

61. client.getConnectionManager().shutdown();

62. }

63.

64. return content;

65. }

66.

67. }

FunctionUtils.java 此类的方法均为static方法

1.View Code

2.

3.package com.sreach.spider;

4.

5.import java.io.BufferedWriter;

6.import java.io.File;

7.import java.io.FileOutputStream;

8.import java.io.IOException;

9.import java.io.OutputStreamWriter;

10.import java.util.regex.Matcher;

11.import java.util.regex.Pattern;

12.

13.public class FunctionUtils

14.{

15.

16. /**

17. * 匹配超链接的正则表达式

18. */

19. private static String pat = "http://www\\.oschina\\.net/code/explore/.*/\\w+\\.[a-zA-Z]+";

20. private static Pattern pattern = Pattern.compile(pat);

21.

22. private static BufferedWriter writer = null;

23.

24. /**

25. * 爬虫搜索深度

26. */

27. public static int depth = 0;

28.

29. /**

30. * 以"/"来分割URL,获得超链接的元素

31. *

32. * @param url

33. * @return

34. */

35. public static String[] divUrl(String url)

36. {

37. return url.split("/");

38. }

39.

40. /**

41. * 判断是否创建文件

42. *

43. * @param url

44. * @return

45. */

46. public static boolean isCreateFile(String url)

47. {

48. Matcher matcher = pattern.matcher(url);

49.

50. return matcher.matches();

51. }

52.

53. /**

54. * 创建对应文件

55. *

56. * @param content

57. * @param urlPath

58. */

59. public static void createFile(String content, String urlPath)

60. {

61. /* 分割url */

62. String[] elems = divUrl(urlPath);

63. StringBuffer path = new StringBuffer();

64.

65. File file = null;

66. for (int i = 1; i < elems.length; i++)

67. {

68. if (i != elems.length - 1)

69. {

70.

71. path.append(elems[i]);

72. path.append(File.separator);

73. file = new File("D:" + File.separator + path.toString());

74.

75. }

76.

77. if (i == elems.length - 1)

78. {

79. Pattern pattern = Pattern.compile("\\w+\\.[a-zA-Z]+");

80. Matcher matcher = pattern.matcher(elems[i]);

81. if ((matcher.matches()))

82. {

83. if (!file.exists())

84. {

85. file.mkdirs();

86. }

87. String[] fileName = elems[i].split("\\.");

88. file = new File("D:" + File.separator + path.toString()

89. + File.separator + fileName[0] + ".txt");

90. try

91. {

92. file.createNewFile();

93. writer = new BufferedWriter(new OutputStreamWriter(

94. new FileOutputStream(file)));

95. writer.write(content);

96. writer.flush();

97. writer.close();

98. System.out.println("创建文件成功");

99. } catch (IOException e)

100. {

101. e.printStackTrace();

102. }

103.

104. }

105. }

106.

107. }

108. }

109.

110. /**

111. * 获取页面的超链接并将其转换为正式的A标签

112. *

113. * @param href

114. * @return

115. */

116. public static String getHrefOfInOut(String href)

117. {

118. /* 内外部链接最终转化为完整的链接格式 */

119. String resultHref = null;

120.

121. /* 判断是否为外部链接 */

122. if (href.startsWith("http://"))

123. {

124. resultHref = href;

125. } else

126. {

127. /* 如果是内部链接,则补充完整的链接地址,其他的格式忽略不处理,如:a href="#" */

128. if (href.startsWith("/"))

129. {

130. resultHref = "http://www.oschina.net" + href;

131. }

132. }

133.

134. return resultHref;

135. }

136.

137. /**

138. * 截取网页网页源文件的目标内容

139. *

140. * @param content

141. * @return

142. */

143. public static String getGoalContent(String content)

144. {

145. int sign = content.indexOf("

 
 

146. String signContent = content.substring(sign);

147.

148. int start = signContent.indexOf(">");

149. int end = signContent.indexOf("

");

150.

151. return signContent.substring(start + 1, end);

152. }

153.

154. /**

155. * 检查网页源文件中是否有目标文件

156. *

157. * @param content

158. * @return

159. */

160. public static int isHasGoalContent(String content)

161. {

162. return content.indexOf("

 
 

163. }

164.

165.}

HrefOfPage.java 此类为获取页面的超链接

1.View Code

2.

3.package com.sreach.spider;

4.

5.public class HrefOfPage

6.{

7. /**

8. * 获得页面源代码中超链接

9. */

10. public static void getHrefOfContent(String content)

11. {

12. System.out.println("开始");

13. String[] contents = content.split("

14. for (int i = 1; i < contents.length; i++)

15. {

16. int endHref = contents[i].indexOf("\"");

17.

18. String aHref = FunctionUtils.getHrefOfInOut(contents[i].substring(

19., endHref));

20.

21. if (aHref != null)

22. {

23. String href = FunctionUtils.getHrefOfInOut(aHref);

24.

25. if (!UrlQueue.isContains(href)

26. && href.indexOf("/code/explore") != -1

27. && !VisitedUrlQueue.isContains(href))

28. {

29. UrlQueue.addElem(href);

30. }

31. }

32. }

33.

34. System.out.println(UrlQueue.size() + "--抓取到的连接数");

35. System.out.println(VisitedUrlQueue.size() + "--已处理的页面数");

36.

37. }

38.

39.}

UrlDataHanding.java 此类主要是从未访问队列中获取url,下载页面,分析url,保存已访问url等操作,实现Runnable接口

1.View Code

2.

3.package com.sreach.spider;

4.

5.public class UrlDataHanding implements Runnable

6.{

7. /**

8. * 下载对应页面并分析出页面对应的URL放在未访问队列中。

9. * @param url

10. */

11. public void dataHanding(String url)

12. {

13. HrefOfPage.getHrefOfContent(DownloadPage.getContentFormUrl(url));

14. }

15.

16. public void run()

17. {

18. while(!UrlQueue.isEmpty())

19. {

20. dataHanding(UrlQueue.outElem());

21. }

22. }

23.}

UrlQueue.java 此类主要是用来存放未访问的URL队列

1.View Code

2.

3.package com.sreach.spider;

4.

5.import java.util.LinkedList;

6.

7.public class UrlQueue

8.{

9. /**超链接队列*/

10. public static LinkedList urlQueue = new LinkedList();

11.

12. /**队列中对应最多的超链接数量*/

13. public static final int MAX_SIZE = 10000;

14.

15. public synchronized static void addElem(String url)

16. {

17. urlQueue.add(url);

18. }

19.

20. public synchronized static String outElem()

21. {

22. return urlQueue.removeFirst();

23. }

24.

25. public synchronized static boolean isEmpty()

26. {

27. return urlQueue.isEmpty();

28. }

29.

30. public static int size()

31. {

32. return urlQueue.size();

33. }

34.

35. public static boolean isContains(String url)

36. {

37. return urlQueue.contains(url);

38. }

39.

40.}

VisitedUrlQueue.java 主要是保存已访问过的URL,使用HashSet来保存,主要是考虑到每个访问过的URL是不同。HashSet刚好符合这个要求

1.View Code

2.

3.package com.sreach.spider;

4.

5.import java.util.HashSet;

6.

7./**

8. * 已访问url队列

9. * @author HHZ

10. *

11. */

12.public class VisitedUrlQueue

13.{

14. public static HashSet visitedUrlQueue = new HashSet();

15.

16. public synchronized static void addElem(String url)

17. {

18. visitedUrlQueue.add(url);

19. }

20.

21. public synchronized static boolean isContains(String url)

22. {

23. return visitedUrlQueue.contains(url);

24. }

25.

26. public synchronized static int size()

27. {

28. return visitedUrlQueue.size();

29. }

30.}

Test.java 此类为测试类

1.View Code

2.

3.import java.sql.SQLException;

4.

5.import com.sreach.spider.UrlDataHanding;

6.import com.sreach.spider.UrlQueue;

7.

8.public class Test

9.{

10. public static void main(String[] args) throws SQLException

11. {

12. String url = "http://www.oschina.net/code/explore/achartengine/client/AndroidManifest.xml";

13. String url1 = "http://www.oschina.net/code/explore";

14. String url2 = "http://www.oschina.net/code/explore/achartengine";

15. String url3 = "http://www.oschina.net/code/explore/achartengine/client";

16.

17.

18. UrlQueue.addElem(url);

19. UrlQueue.addElem(url1);

20. UrlQueue.addElem(url2);

21. UrlQueue.addElem(url3);

22.

23. UrlDataHanding[] url_Handings = new UrlDataHanding[10];

24.

25. for(int i = 0 ; i < 10 ; i++)

26. {

27. url_Handings[i] = new UrlDataHanding();

28. new Thread(url_Handings[i]).start();

29. }

30.

31. }

32.}

说明一下:由于抓取的是针对oschina的,所以里面的url正则表达式不适合其他网站,需要自己修改一下。你也可以写成xml来配置。

人打赏

0人 点赞

主帖获得的天涯分:0

举报 |

楼主

|

楼主发言:1次 发图:0张 | 添加到话题 |

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值