網(wǎng)絡爬蟲(又被稱為網(wǎng)頁蜘蛛,網(wǎng)絡機器人,在FOAF社區(qū)中間,更經(jīng)常的稱為網(wǎng)頁追逐者),是一種按照一定的規(guī)則,自動地抓取萬維網(wǎng)信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲?!俣劝倏?/p>
爬蟲最基礎的操作其實就是分析靜態(tài)網(wǎng)頁,從而獲取有價值的信息?,F(xiàn)在的網(wǎng)頁一般均為Html格式的,當然http請求也會返回xml,json等數(shù)據(jù)格式。在入門篇我們以html為例。
分析需求
我打算在鏈家網(wǎng)上爬取北京一個小區(qū)的房價信息,每天爬一次,如果有房價信息更新,或者有新房,則在log文件里面打一條log。
步驟
獲取小區(qū)網(wǎng)頁html->分析網(wǎng)頁元素->獲取有用的信息->比對已經(jīng)存在的房價信息->打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)頁檢查元素即可,一般瀏覽器都會自帶匹配,慢慢往下尋找,可以找到houselist,如下圖。所以我需要的信息就全部在這個里面了。

鏈家網(wǎng)頁面元素分析
查看一下每一條item的信息,并找出自己關心的幾個元素,title,price等。

每套房子的信息
獲取有用的信息
然后我們要做的就是從http請求返回的字符串中找到相應的信息。用正則表達式匹配是一種不錯的選擇。其中()所包括的表示一個我們所關心的元素,最后正則表達式如下所示。
// 房產(chǎn)數(shù)據(jù)匹配正則
public static final String houseInfoExpression = "data-index=\"(.+?)\".+?" +//標簽
"data-id=\"(.+?)\">.*?" +//數(shù)據(jù)id
"<h2><a.+?title=.+?>(.+?)[ ]{0,}</a>.*?" +//title
"region.+?>(.+?)[ ]{0,}<.*?" +//小區(qū)
"meters.+?>(.+?)[ ]{0,}<.*?" +//大小
"price.+?num.+?>(.+?)</span>.*?" +//價格
"price-pre.+?>(.+?)</div>";//每平米價格
下面要做的就是去匹配數(shù)據(jù)了。java中主要用Pattern和Matcher去做正則匹配
//獲取當前頁的房產(chǎn)信息
ArrayList<HouseInfo> results = new ArrayList<HouseInfo>();
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(targetStr);
boolean isFind = matcher.find();
while(isFind){//如果匹配到記錄相應的信息。
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);
}