轉載請注明出處:[http://blog.csdn.net/xiaojimanman/article/details/44831003](http://blog.csdn.net/xiaojimanman/article/details/44831003)
[http://www.llwjy.com/blogdetail/a2d1df2b69f17696865f086777996fb1.html](http://www.llwjy.com/blogdetail/a2d1df2b69f17696865f086777996fb1.html)
個人博客站已經上線了,網址 [www.llwjy.com](#) ~歡迎各位吐槽~
-------------------------------------------------------------------------------------------------
之前的博客,已經介紹了如何基于Lucene來開發站內搜索的大部分內容,剩下的就是一些業務邏輯部分的開發以及接口的定義,這一部分在數據采集介紹完畢之后再來介紹。如果你已經對網絡爬蟲已經相當熟悉,可以忽略之后的幾篇博客~
在之前的博客[《基于HttpClient實現網絡爬蟲~以百度新聞為例》](http://www.llwjy.com/blogdetail/5c71c9b34b6da162fd0751fc80f35a5e.html)對自己的爬蟲底層實現以及如何分析網頁結構,抓取網頁內容做了部分介紹,對之前介紹過的內容就不再過多介紹了,下面就重點說一下最新底層更新情況。
**CrawlBase**
在之前的CrawlBase類中,自己是這樣定義HttpClient的,這樣帶來的后果就是在多線程的情況下會出現一系列的問題,所以對HttpClient的定義做了如下修改:
修改前:
~~~
private static HttpClient httpClient = new HttpClient();
~~~
修改后:
~~~
private static MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
private static HttpClient httpClient = new HttpClient(httpConnectionManager);
~~~
同時還支持手動輸入網址含有中文,通過CrawlListPageBase類獲取的下一跳的網址是不會出現該問題的。具體的修改是對URL做一次處理,具體方法如下:
~~~
private String encodeUrlCh(String url) {
try {
return DoRegex.encodeUrlCh(url);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return url;
}
}
~~~
其他應該沒有太多的修改,最新的CrawlBase類還請訪問[http://www.llwjy.com/source/com.lulei.crawl.CrawlBase.html](http://www.llwjy.com/source/com.lulei.crawl.CrawlBase.html)
**ps:**要獲取個人最新java源代碼,請訪問[http://www.llwjy.com/source.html](http://www.llwjy.com/source.html),只需要在輸入框內輸入引用的類,即可檢索出最新源碼,比如:輸入?com.lulei.crawl.CrawlBase 即可查看 CrawlBase 類的相信信息。
**CrawlListPageBase**
CrawlListPageBase類是自己對更新列表這一類的網頁做的一次封裝,從網頁中只獲取下一跳的網址。下面就按照縱橫中文小說網站的實際情況來介紹如何使用CrawlListPageBase類來實現更新列表頁信息的獲取。
訪問縱橫中文網,可以很容易的就找到免費小說的更新列表頁,網址:http://book.zongheng.com/store/c0/c0/b9/u0/p1/v0/s9/t0/ALL.html ,對頁面做簡單的分析即可發現下圖中的內容就是最新更新的小說書目列表。

通過鼠標右鍵--查看網頁源代碼 ?不難找到這些數據在網頁中的位置,如下圖:

而紅色框出來的內容就是我們需要的下一跳網址,因此我們可以很簡單的確定獲取該信息的正則表達式是 :?<a class="fs14" href="(.*?)"?,因此我們需要創建CrawlListPageBase的一個子類UpdateList,讓它來完成縱橫免費小說更新列表頁信息的采集,對CrawlListPageBase類中的抽象方法做具體的實現,如下:
~~~
@Override
public String getUrlRegexString() {
return "<a class=\"fs14\" href=\"(.*?)\"";
}
@Override
public int getUrlRegexStringNum() {
return 1;
}
~~~
用HttpClient 模擬瀏覽器的行為,需要對請求做一點偽裝,由于縱橫的防爬蟲策略做的并不是太好,所以只需要做Referer和User-Agent即可,具體如下:
~~~
private static HashMap<String, String> params;
/**
* 添加相關頭信息,對請求進行偽裝
*/
static {
params = new HashMap<String, String>();
params.put("Referer", "http://book.zongheng.com");
params.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36");
}
~~~
在添加構造方法時,只需要使用params即可,如下:
~~~
public UpdateList(String urlStr) throws IOException {
super(urlStr, "utf-8", params);
}
~~~
這樣UpdateList子類計算完成了,使用getPageUrls()方法即可獲取頁面內我們需要的鏈接。
經過眾多數據的測試,這時候你不難發現,縱橫中文網的更新列表上的數目并不是全部來自縱橫中文網,還有其他的站,因此需要對這些數據做簡單的過濾,代碼如下:
~~~
public List<String> getPageUrls(boolean exceptOther){
List<String> urls = getPageUrls();
if (exceptOther) {
List<String> exceptUrls = new ArrayList<String>();
for (String url : urls) {
if (url.indexOf("zongheng") > 0) {
exceptUrls.add(url);
}
}
return exceptUrls;
}
return urls;
}
~~~
我們使用上述方法代替之前說的那個方法即可選擇是否舍棄這些網址,在這個項目中,我們選擇舍棄。經過上述步驟,縱橫中文的更新列表頁的采集模版就完成了。
**運行結果**

**源代碼**
最新源代碼可以訪問:[http://www.llwjy.com/source/com.lulei.crawl.novel.zongheng.UpdateList.html](http://www.llwjy.com/source/com.lulei.crawl.novel.zongheng.UpdateList.html)
~~~
/**
*@Description: 更新列表頁
*/
package com.lulei.crawl.novel.zongheng;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.lulei.crawl.CrawlListPageBase;
public class UpdateList extends CrawlListPageBase{
private static HashMap<String, String> params;
/**
* 添加相關頭信息,對請求進行偽裝
*/
static {
params = new HashMap<String, String>();
params.put("Referer", "http://book.zongheng.com");
params.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36");
}
public UpdateList(String urlStr) throws IOException {
super(urlStr, "utf-8", params);
}
@Override
public String getUrlRegexString() {
return "<a class=\"fs14\" href=\"(.*?)\"";
}
@Override
public int getUrlRegexStringNum() {
return 1;
}
/**
* @param exceptOther
* @return
* @Author:lulei
* @Description: 是否排除非縱橫的書籍
*/
public List<String> getPageUrls(boolean exceptOther){
List<String> urls = getPageUrls();
if (exceptOther) {
List<String> exceptUrls = new ArrayList<String>();
for (String url : urls) {
if (url.indexOf("zongheng") > 0) {
exceptUrls.add(url);
}
}
return exceptUrls;
}
return urls;
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
UpdateList updateList = new UpdateList("http://book.zongheng.com/store/c0/c0/b9/u0/p1/v0/s9/t0/ALL.html");
for (String s : updateList.getPageUrls(true)) {
System.out.println(s);
}
}
}
~~~
----------------------------------------------------------------------------------------------------
ps:最近發現其他網站可能會對博客轉載,上面并沒有源鏈接,如想查看更多關于 [基于lucene的案例開發](http://www.llwjy.com/blogtype/lucene.html) 請[點擊這里](http://blog.csdn.net/xiaojimanman/article/category/2841877)。或訪問網址http://blog.csdn.net/xiaojimanman/article/category/2841877
- 前言
- 寫在開始之前
- lucene初始認知
- 索引數學模型
- 索引文件結構
- 創建索引
- 搜索索引
- 分詞器介紹
- Query查詢
- IndexSearcher中檢索方法
- 更新說明
- 案例初識
- JsonUtil &amp; XmlUtil
- 基ClassUtil &amp; CharsetUtil
- ParseUtil &amp; ParseRequest
- 數據庫連接池
- 實現實時索引基本原理
- 實時索引管理類IndexManager
- 實時索引的檢索
- 實時索引的修改
- 查詢語句創建PackQuery
- 縱橫小說更新列表頁抓取
- 縱橫小說簡介頁采集
- 縱橫小說章節列表采集
- 縱橫小說閱讀頁采集
- 縱橫小說數據庫設計
- 縱橫小說數據庫操作
- 縱橫小說分布式采集