網(wǎng)絡(luò)爬蟲(又被稱為網(wǎng)頁蜘蛛,網(wǎng)絡(luò)機(jī)器人,在FOAF社區(qū)中間,更經(jīng)常的稱為網(wǎng)頁追逐者),是一種按照一定的規(guī)則,自動(dòng)地抓取萬維網(wǎng)信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動(dòng)索引、模擬程序或者蠕蟲?!俣劝倏?/p>
爬蟲最基礎(chǔ)的操作其實(shí)就是分析靜態(tài)網(wǎng)頁,從而獲取有價(jià)值的信息?,F(xiàn)在的網(wǎng)頁一般均為Html格式的,當(dāng)然http請求也會(huì)返回xml,json等數(shù)據(jù)格式。在入門篇我們以html為例。
分析需求
我打算在鏈家網(wǎng)上爬取北京一個(gè)小區(qū)的房價(jià)信息,每天爬一次,如果有房價(jià)信息更新,或者有新房,則在log文件里面打一條log。
步驟
獲取小區(qū)網(wǎng)頁html->分析網(wǎng)頁元素->獲取有用的信息->比對已經(jīng)存在的房價(jià)信息->打log
獲取網(wǎng)頁
這里我們用java自帶的httpclient發(fā)送http請求并用字符串存取。
public String httpGet(String url)
{
String result = "";
BufferedReader in = null;
try {
URL realUrl = new URL(url);
System.out.println(realUrl + "\n" + url);
urlConnection = realUrl.openConnection();
urlConnection.connect();
in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
System.out.println(urlConnection.getHeaderFields());
String line;
while((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e){
System.out.println("發(fā)送get請求異常!" + e);
e.printStackTrace();
} finally {
try{
if(in != null){
in.close();
}
}catch (Exception e2){
e2.printStackTrace();
}
}
return result;
}
分析網(wǎng)頁元素
打開網(wǎng)頁檢查元素即可,一般瀏覽器都會(huì)自帶匹配,慢慢往下尋找,可以找到houselist,如下圖。所以我需要的信息就全部在這個(gè)里面了。

查看一下每一條item的信息,并找出自己關(guān)心的幾個(gè)元素,title,price等。

獲取有用的信息
然后我們要做的就是從http請求返回的字符串中找到相應(yīng)的信息。用正則表達(dá)式匹配是一種不錯(cuò)的選擇。其中()所包括的表示一個(gè)我們所關(guān)心的元素,最后正則表達(dá)式如下所示。
// 房產(chǎn)數(shù)據(jù)匹配正則
public static final String houseInfoExpression = "data-index=\"(.+?)\".+?" +//標(biāo)簽
"data-id=\"(.+?)\">.*?" +//數(shù)據(jù)id
"<h2><a.+?title=.+?>(.+?)[ ]{0,}</a>.*?" +//title
"region.+?>(.+?)[ ]{0,}<.*?" +//小區(qū)
"meters.+?>(.+?)[ ]{0,}<.*?" +//大小
"price.+?num.+?>(.+?)</span>.*?" +//價(jià)格
"price-pre.+?>(.+?)</div>";//每平米價(jià)格
下面要做的就是去匹配數(shù)據(jù)了。java中主要用Pattern和Matcher去做正則匹配
//獲取當(dāng)前頁的房產(chǎn)信息
ArrayList<HouseInfo> results = new ArrayList<HouseInfo>();
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(targetStr);
boolean isFind = matcher.find();
while(isFind){//如果匹配到記錄相應(yīng)的信息。
HouseInfo houseInfo = new HouseInfo();
houseInfo.setHouseIndex(Integer.parseInt(matcher.group(1)));
houseInfo.setHouseDataId(matcher.group(2));
houseInfo.setHouseTitle(matcher.group(3));
houseInfo.setHouseRegion(matcher.group(4));
houseInfo.setHouseArea(matcher.group(5));
houseInfo.setHousePrice(Integer.parseInt(matcher.group(6)));
houseInfo.setHousePricePer(matcher.group(7));
JSONObject jsonObject = new JSONObject(houseInfo);
System.out.println(jsonObject);
}