Posted on 2008-09-13 08:33
Jason Chen 阅读(1243)
评论(0) 编辑 收藏
最近我们iwode在搞SEO,由于我们原来的网站上面并没有太注重加入这方面的内容,所以基本上我们的网站除了购物流程和品牌介绍外并没有太多其他的内容,感觉上我们的网站会好闷,所以我们想先实现一个功能,就是从一些RSS抓取内容,把正文内容转存到数据库包括所有的分页,同时去掉正文中的超链接(不链接到别人的网站),把图片转存到本地同时修改<img>标签的src路径。之后,我们可以根据数据库的内容,维护文章,改变样式,然后放到网站上。
由于RSS本质上就是一个xml文档,所以第一步要做的就是取得网络上的一个xml文档,使其可操作。我用URL打开一个到该RSS的流,然后根据读回来的流建一个DOM,这样就可以读取xml文档中的内容。
在一个RSS中,其中<item>标签记录着文章的信息,我关心的是其中的title,pubDate,link三个内容。title是文章的标题,pubDate是发布时间,link是该文章的链接。现在我们可以开始读取文章的内容,方法也是通过一个URL打开到文章的流,然后从流中把文章的内容(一个html)读到本地,然后再进行其他处理。
在所读取的RSS的文章的正文内容都放在“<div class="Con"></div>”中,而分页信息则放在<div class="LP T H"></div>”中。取正文内容只需把“<div class="Con"></div>”中的内容提取出来即可。要去掉文章中的链接信息和得到图片,首先要找出正文中,所有的超链接和<img>标签,我是通过实用正则表达式来实现。要去掉链接信息,我们需要把<a>和</a>标签替换成空字符串就可以了。取得<img>标签后,要找出src属性的值,它记录了图片的URL。依据该URL,实用ImageIO,可以很方便地把图片写到本地,最后要做的得就是把就是把src的值替换为刚才写到本地的文件。
具体的代码如下:
1 /**
2 *
3 */
4 package com.iwode.jason;
5
6 import java.awt.image.BufferedImage;
7 import java.io.*;
8 import java.net.URL;
9 import java.text.SimpleDateFormat;
10 import java.util.ArrayList;
11 import java.util.Date;
12 import java.util.List;
13 import java.util.regex.*;
14 import org.w3c.dom.*;
15 import javax.imageio.ImageIO;
16
17 /**
18 * @author Jason
19 * @version 创建时间:2008-9-10 下午09:57:29
20 * @contact 联系方式: mailto:crjjason@163.com
21 */
22 public class RSSTester {
23
24 /**
25 * @param args
26 */
27 public static void main(String[] args) {
28 RssGetter rssGetter = new RssGetter();
29 rssGetter.getRssSource();
30 }
31 }
32
33 class RssGetter {
34 private String url;
35
36 public String getUrl() {
37 return url;
38 }
39
40 public void setUrl(String url) {
41 this.url = url;
42 }
43
44 public RssGetter() {
45 this.url = "http://news.tyloo.com/mens.rss";
46 }
47
48 /**
49 * 把RSS存到数据库
50 */
51 public void getRssSource() {
52 try {
53 URL url = new URL(this.url);
54 InputStream is = url.openStream();
55 try {
56 javax.xml.parsers.DocumentBuilder builder = javax.xml.parsers.DocumentBuilderFactory
57 .newInstance().newDocumentBuilder();
58 Document doc = builder.parse(is);
59 NodeList items = doc.getElementsByTagName("item");
60 for (int i = 0; i < items.getLength(); i++) {
61 Node item = items.item(i);
62 NodeList childs = item.getChildNodes();
63 String title = "";
64 String link = "";
65 String pubDate = "";
66 for (int j = 0; j < childs.getLength(); j++) {
67 Node child = childs.item(j);
68 String nodeName = child.getNodeName().trim();
69 if (nodeName.equals("title")) {
70 title = child.getTextContent().trim();
71 } else if (nodeName.equals("link")) {
72 link = child.getTextContent().trim();
73 } else if (nodeName.equals("pubDate")) {
74 pubDate = child.getTextContent();
75 pubDate = pubDate.replaceAll("T", " ");
76 }
77 }
78 Date date = new Date();
79 if (pubDate != null && !pubDate.equals("")) {
80 SimpleDateFormat df = new SimpleDateFormat(
81 "yyyy-MM-dd HH:mm:ss");
82 date = df.parse(pubDate);
83 }
84 URL linkUrl = new URL(link);
85 InputStream linkIs = linkUrl.openStream();
86 StringBuilder content = new StringBuilder();
87 byte[] bytes = new byte[1024];
88 while (linkIs.read(bytes) != -1) {
89 String bytes2utf8 = new String(bytes, "utf-8");
90 content.append(bytes2utf8);
91 }
92 String needText = content.toString();// needText为HTML的内容
93 // 取正文内容
94 this.getLinkInfo(needText,true);
95 // 取分页信息
96 this.getPages(needText);
97 }
98 } catch (Exception e) {
99 e.printStackTrace();
100 } finally {
101 is.close();
102 }
103 } catch (IOException io) {
104 io.printStackTrace();
105 }
106 }
107
108 /**
109 * 取正文信息
110 * @param path
111 * @param isLink 标识path是链接还是html内容
112 * @throws Exception
113 */
114 private void getLinkInfo(String path, boolean isLink) throws Exception {
115 String input = path;
116 if (!isLink) {
117 URL linkUrl = new URL(path);
118 InputStream linkIs = linkUrl.openStream();
119 StringBuilder content = new StringBuilder();
120 byte[] bytes = new byte[1024];
121 while (linkIs.read(bytes) != -1) {
122 String bytes2utf8 = new String(bytes, "utf-8");
123 content.append(bytes2utf8);
124 }
125 input = content.toString();// needText为HTML的内容
126 }
127 int beginIndex = -1, endIndex = -1;
128 beginIndex = input.indexOf("<body");
129 endIndex = input.indexOf("</body>");
130 String needText = "";
131 if (beginIndex != -1 && endIndex != -1) {
132 needText = input.substring(beginIndex, endIndex);
133 beginIndex = needText.indexOf(">");
134 needText = needText.substring(beginIndex + 1);
135 }
136 String bodyText = this.parseContent(needText);// ok
137 bodyText = this.removeLinks(bodyText);// ok
138 bodyText = this.processImages(bodyText);// ok
139 System.out.println(bodyText);
140 }
141 /**
142 * 取分页信息
143 * @param input
144 * @throws Exception
145 */
146 private void getPages(String input) throws Exception {
147 int beginIndex = -1, endIndex = -1;
148 beginIndex = input.indexOf("<div class=\"LP T H\">");
149 String needText = "";
150 // 如果页面有分页
151 if (beginIndex != -1) {
152 needText = input.substring(beginIndex);
153 beginIndex = needText.indexOf(">");
154 endIndex = needText.indexOf("</div>");
155 if (endIndex != -1) {
156 needText = needText.substring(beginIndex + 1, endIndex);// 存储所有分页链接信息
157 String regEx = "<a [^>]*>[^<]*</a>";
158 Pattern p = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
159 Matcher m = p.matcher(needText);
160 List<String> as = new ArrayList<String>();
161 while (m.find()) {
162 as.add(m.group());
163 }
164 for (String s : as) {
165 if (s.indexOf("onPage") != -1 || s.indexOf("[下一页]") != -1) {
166 continue;
167 }
168 beginIndex = -1;
169 endIndex = -1;
170 beginIndex = s.indexOf("href=");
171 String path = "";
172 if (beginIndex != -1) {
173 path = s.substring(beginIndex + 6);
174 endIndex = path.indexOf("\"");
175 if (endIndex != -1) {
176 path = path.substring(0, endIndex);
177 } else {
178 path = "";
179 }
180 }
181 if (!path.equals("")) {
182 this.getLinkInfo(path,false);
183 }
184 }
185 }
186 }
187 }
188
189 /**
190 * 取得文章正文内容
191 *
192 * @param contentText
193 * @return
194 * @throws Exception
195 */
196 private String parseContent(String contentText) throws Exception {
197 String content = "";
198 int beginIndex = -1;
199 int endIndex = -1;
200 beginIndex = contentText.indexOf("<div class=\"Con\">");
201 if (beginIndex != -1) {
202 content = contentText.substring(beginIndex);
203 endIndex = content.indexOf("</div>");
204 if (endIndex != -1) {
205 content = content.substring(0, endIndex + 6);
206 }
207 }
208 return content;
209 }
210
211 /**
212 * 去掉文章中的<a>
213 *
214 * @param input
215 * @return
216 */
217 private String removeLinks(String input) {
218 String output = input;
219 // 开头的<a>的正则表达式
220 String regEx = "<a [^>]*>";
221 Pattern p = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
222 Matcher m = p.matcher(input);
223 output = m.replaceAll("");
224 // 结尾的</a>的正则表达式
225 regEx = "</a>";
226 p = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
227 m = p.matcher(output);
228 output = m.replaceAll("");
229 return output;
230 }
231
232 /**
233 * 处理文章中的图片
234 *
235 * @param input
236 * @return
237 */
238 private String processImages(String input) {
239 String output = input;
240 String regEx = "<img [^>]*>";
241 Pattern p = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
242 Matcher m = p.matcher(input);
243 List<String> imgs = new ArrayList<String>();
244 // 读取所有<img>标签
245 while (m.find()) {
246 imgs.add(m.group());
247 }
248 // 把图存到本地,并替换<img>标签的src值
249 for (String img : imgs) {
250 int begin = -1;
251 int end = -1;
252 String path = "";
253 if (img.indexOf("src=\"") != -1) {
254 begin = img.indexOf("src=\"");
255 path = img.substring(begin + 5);
256 end = path.indexOf("\"");
257 if (end != -1) {
258 path = path.substring(0, end);
259 } else {
260 path = "";
261 }
262 }
263 if (img.indexOf("src='") != -1) {
264 begin = img.indexOf("src='");
265 path = img.substring(begin + 5);
266 end = path.indexOf("'");
267 if (end != -1) {
268 path = path.substring(0, end);
269 } else {
270 path = "";
271 }
272 }
273 if (!path.equals("")) {
274 String filepath = this.writeImageToServer(path);
275 // System.out.println(filepath);
276 while (filepath.indexOf('\\') != -1) {
277 filepath = filepath.replace('\\', '/');
278 }
279 output = output.replaceAll(path, filepath);
280 }
281 }
282 // System.out.println(output);
283 return output;
284 }
285
286 /**
287 * 把图片写到数据库
288 *
289 * @param path
290 * 原图片路径
291 * @return 本地图片路径
292 */
293 private String writeImageToServer(String path) {
294 String filename = "";
295 try {
296 // 取图像的格式
297 int begin = path.lastIndexOf(".");
298 String suffix = path.substring(begin + 1);
299 // 读取图像
300 URL url = new URL(path);
301 BufferedImage image = ImageIO.read(url);
302 filename = "D:\\pics\\" + new Date().getTime() + "." + suffix;
303 File file = new File(filename);
304 FileOutputStream fos = new FileOutputStream(file);
305 ImageIO.write(image, suffix, fos);
306 fos.close();
307 } catch (IOException io) {
308 io.printStackTrace();
309 }
310 return filename;
311 }
312 }
313
314