大家好, 前几篇文章介绍的 URL 都是返回 html 内容的, 然后再从 HTML 字符串里解析出我们想要的数据 但是, 随着前端编程技术的发展, 至少十多年前开始 ajaxjson 等技术就已经是主流了我们在网页上看到的很多数据, 都是 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/jsonapplication/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=苏州&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=苏州&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_数据工程师?labelWords=sug&fromSearch=true&suginput=数据工程")
- .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 等等
来源: https://juejin.im/post/5a90eaf4f265da4e9a4973f5