上一篇:Java網路爬蟲實操(4)
大家好,前幾篇文章介紹的URL都是返回HTML內容的,然後再從HTML字串裡解析出我們想要的資料。 但是,隨著前端程式設計技術的發展,至少十多年前開始ajax、json等技術就已經是主流了。我們在網頁上看到的很多資料,都是ajax非同步方式請求伺服器,然後以json資料格式返回響應結果並載入到網頁上的。
本篇文章的目標:使用NetDiscovery爬蟲框架,使用GET和POST兩種方式,獲取我們想要的json資料。
1) 獲取城市名稱
-
在選擇城市的下拉框裡有各個省份的主流城市名稱:
-
開啟瀏覽器,找到提供這個資料來源的連結:
- 基於NetDiscovery現在開始寫程式碼(程式碼僅僅為了演示如何獲取到資料)
Main類
package com.cv4j.netdiscovery.example;
import com.cv4j.netdiscovery.core.Spider;
import com.cv4j.netdiscovery.core.domain.HttpMethod;
import com.cv4j.netdiscovery.core.domain.Request;
public class TestSpider {
public static void main(String[] args) {
String url = "https://www.zhipin.com/common/data/city.json";
Request request = new Request(url)
.httpMethod(HttpMethod.GET); //GET不設定也可以的,預設就是
Spider.create()
.name("getcitys")
.request(request)
.parser(new TestParser())
.run();
}
}
複製程式碼
Parser類
package com.cv4j.netdiscovery.example;
import com.cv4j.netdiscovery.core.config.Constant;
import com.cv4j.netdiscovery.core.domain.Page;
import com.cv4j.netdiscovery.core.parser.Parser;
public class TestParser implements Parser {
@Override
public void process(Page page) {
try {
String response = page.getField(Constant.RESPONSE_JSON).toString();
System.out.println("response = "+response);
} catch(Exception e) {
}
}
}
複製程式碼
- 程式執行結果
2) 獲取招聘崗位
-
同樣的方法,先用瀏覽器人肉分析一下目標物件:
-
再看一下要傳遞的引數
要分得清GET和POST傳遞引數的區別,
對於POST引數的型別要有概念: application/json、application/x-www-form-urlencode等
- 開始寫程式碼 Main類
package com.cv4j.netdiscovery.example;
import com.cv4j.netdiscovery.core.Spider;
import com.cv4j.netdiscovery.core.config.Constant;
import com.cv4j.netdiscovery.core.domain.HttpMethod;
import com.cv4j.netdiscovery.core.domain.HttpRequestBody;
import com.cv4j.netdiscovery.core.domain.Request;
import java.util.HashMap;
import java.util.Map;
public class TestSpider {
public static void main(String[] args) {
String url = "https://www.lagou.com/jobs/positionAjax.json?city=%E8%8B%8F%E5%B7%9E&needAddtionalResult=false&isSchoolJob=0";
Map<String,Object> postParams = new HashMap<>();
postParams.put("first",true);
postParams.put("pn",1);
postParams.put("kd","資料工程師");
Request request = new Request(url)
.httpMethod(HttpMethod.POST)
.httpRequestBody(HttpRequestBody.form(postParams, Constant.UTF_8));
Spider.create()
.name("getpositions")
.request(request)
.parser(new TestParser())
.run();
}
}
複製程式碼
Parser類同上TestParser
但是,得到的結果是:
為什麼? 不要被提示文字所迷惑,明明是第一次訪問,不可能是頻繁操作導致的。 返回這種結果是網站服務端設計的一種反爬蟲手段。 網站服務端識別到不是人在用瀏覽器訪問它,所以返回這個結果出來。 所以,程式要做到儘量真實的模擬瀏覽器的操作,讓網站服務端認為是瀏覽器在訪問。
如何儘量真實模擬? 用程式把request裡的資料都儘量搞到程式裡
按照經驗,一般先設定一下Referer和User-Agent(參考http協議)
新的Main類
package com.cv4j.netdiscovery.example;
import com.cv4j.netdiscovery.core.Spider;
import com.cv4j.netdiscovery.core.config.Constant;
import com.cv4j.netdiscovery.core.domain.HttpMethod;
import com.cv4j.netdiscovery.core.domain.HttpRequestBody;
import com.cv4j.netdiscovery.core.domain.Request;
import java.util.HashMap;
import java.util.Map;
public class TestSpider {
public static void main(String[] args) {
String url = "https://www.lagou.com/jobs/positionAjax.json?city=%E8%8B%8F%E5%B7%9E&needAddtionalResult=false&isSchoolJob=0";
Map<String,Object> postParams = new HashMap<>();
postParams.put("first",true);
postParams.put("pn",1);
postParams.put("kd","資料工程師");
Request request = new Request(url)
.httpMethod(HttpMethod.POST)
.referer("https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%B7%A5%E7%A8%8B%E5%B8%88?labelWords=sug&fromSearch=true&suginput=%E6%95%B0%E6%8D%AE%E5%B7%A5%E7%A8%8B")
.ua("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36")
.httpRequestBody(HttpRequestBody.form(postParams, Constant.UTF_8));
Spider.create()
.name("getpositions")
.request(request)
.parser(new TestParser())
.run();
}
}
複製程式碼
服務端終於返回有資料的結果了(資料是否有用,有待進一步分析):
3) 總結
本文的知識點包括:掌握ajax非同步執行的概念、瞭解json資料格式、學會使用除錯工具,比如谷歌瀏覽器的Developer Tools等等。
最重要還是對http協議要有了解。
想自己親自操作一遍的朋友們,請訪問github上的NetDiscovery,您的點贊是框架不斷完善的動力!
本文僅用於交流程式設計技術,不建議頻繁訪問他人的生產伺服器
下一篇:Java網路爬蟲實操(6)