Java網路爬蟲實操(5)

sinkinka發表於2018-02-24

上一篇: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等

POST請求

  • 開始寫程式碼 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裡的資料都儘量搞到程式裡

http請求的headers

按照經驗,一般先設定一下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)

相關文章