上篇文章,介紹了我2012年實現的一個內容聚合網站,經過正則表達式抽取網頁內容,並提供了代碼實現。javascript
本文將進一步介紹其實現過程:html
1、網頁結構分析 前端
在2012年左右,JavaScript還遠沒有今天這麼強大,當時html是網頁的骨架,css進行風格裝飾,javascript提供動做。java
[注]在當今動輒 React、Angular、Vue之類技術作前端,前端一棧式開發的背景下,內容抽取也許大不同。正則表達式
從網頁頁面上抽取內容,須要分析其html結構。通常狀況下是經過table、ul、li、div之類的標籤提供一個列表,內容頁面通常是經過div實現的。ide
好比博客園的「精華區」,經過Chrome的F12,post
而後「查看元素」,整個列表頁面是經過div支撐起來的,每一條也是一個div;網站
其中標題和連接是在<div class="post_item">下的<a class="titlelnk"中;url
發表時間,是在<a href=和<span class="article_comment">之間。
2、內容提取
知道告終構,下一步就是如何提取內容了。
一、提取整個列表部分
該部分相對比較簡單,找到列表部分的起始、結束部分就能夠了。
如博客園精華部分的起始是:<div id="post_list">,結束是:</div>。
通常狀況下,開始位置比較容易肯定,但結束位置這麼些用正則表達式在結束標籤是div的時候是沒法獲取內容的。這種狀況下要找到結束標籤的下一個標籤, 好比:
<script>editorPickStat(); aggSite.user.getUserInfo();</script>
1 // 得到網址所在的匹配區域部分 2 3 private static String getContentArea(String urlContent, String strAreaBegin,String strAreaEnd) { 4 5 int pos1 = 0, pos2 = 0; 6 pos1 = urlContent.indexOf(strAreaBegin) + strAreaBegin.length(); 7 pos2 = urlContent.indexOf(strAreaEnd, pos1); 8 return urlContent.substring(pos1, pos2); 9 }
而後經過正則表達式獲取一個列表:
1 Pattern pt = Pattern.compile(rb.getRegex()); 2 Matcher mt = pt.matcher(contentArea); 3 4 while (mt.find()) {
二、提取單條記錄
方法同提取內容部分差很少,如單條記錄的起始標籤爲<div class="post_item">,結束標籤相對來講也比較難肯定。
獲取單條記錄,並去除空格之類的無用字符:
1 String rowContent = mt.group(); 2 3 rowContent = rowContent.replaceAll(rb.getRemoveRegex(), "");
三、提取出標題
取出標題用的是 >.?</a>或者title=.?>,而且要去除空格和多餘的字符,須要用到相似:<li>|</li>|(<img)([\s\S]?)(>)|(<div)([\s\S]?)(>)|</div>或者(<table)([\s\S]?)(>)|<tr>|(<td)([\s\S]?)(>)|</td>|</tr>|(<table)([\s\S]*?)(>)之類的。
1 // 獲取標題 2 3 Matcher title = Pattern.compile(rb.getTitleRegex()).matcher(rowContent); 6 7 while (title.find()) { 8 9 String s = title.group().replaceAll("||>|</a>|\[.*?\]|</l>",""); 10 11 if(s ==null || s.trim().length()<=0){ 13 s = "error"; 15 } 17 tuBean.setTitle(s); 18 19 }
四、提取出超連接
提取出超連接,須要用到 href=.?target=或者href=.?.> 或者 href=.*?title。要根據實際狀況配置。
1 // 獲取網址 2 3 Matcher myurl = Pattern.compile(rb.getUrlRegex()).matcher( 4 5 rowContent); 6 7 while (myurl.find()) { 8 9 String u = myurl.group().replaceAll( 10 11 "href=|"|>|target=|_blank|title", ""); 12 13 u = u.replaceAll("'|\\", ""); 14 15 if(u!=null && (u.indexOf("http://")==-1)){ 16 17 tuBean.setUrl(rb.getPrefix() + u); 18 19 }else{ 20 21 tuBean.setUrl(u); 22 23 } 24 25 } 26 27 if(tuBean.getUrl() ==null){ 28 29 tuBean.setUrl("error"); 30 31 }
五、提取出發表時間
不一樣的時間格式,獲取方法是不同的。這個也是用正則表達式獲取:比較常規的
[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}
或者:
[0-9]{4}-[0-9]{2}-[0-9]{1,2}
1 // 獲取時間 3 Matcher d = Pattern.compile(rb.getDateRegex()).matcher(rowContent); 5 while (d.find()) { 6 7 tuBean.setDeliveryDate(d.group()); 8 9 }
原文出處:https://www.cnblogs.com/siweihz/p/12150017.html