GraphQL 是一种用于 API 的查询语言,是由 Facebook 开源的一种用于提供数据查询服务的抽象框架。在服务端 API 开发中,不少时候定义一个接口返回的数据相对固定,所以要得到更多信息或者只想获得某部分信息时,基于 RESTful API 的接口就显得不那么灵活。而 GraphQL 对 API 中的数据提供了一套易于理解的完整描述,使得客户端可以准确地得到它须要的数据,并且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。 目前,LeetCode 和 GitHub 都借助 GraphQL 来设计,提供了更大的灵活性,对于想借助 GitHub 来了解 GraphQL 可直接访问 GraphQL API v4 ,或者参考 GraphQL 实战:Github V4 API使用。而对于在 LeetCode 上使用 GraphQL 查询,相对资料少一些,所以在这,我主要以 LeetCode 为例,来作讲解(实际上是由于本身业余刷题时突发奇想,想写一个爬虫。java
若是直接搜索以 Java 语言为载体的 GraphQL 的话,一大部分搜索结果都是介绍使用 graphql-java 来搭建查询服务,而咱们的目的是利用 GraphQL 来获取想要的数据,并不是本身搭建一个查询服务,所以若是一开始就选错了工具,就会致使后面的方向都是错误的。 以 LeetCode 第一题 1.Two Sum 为例,获取其后端发送过来的数据。利用 F12 功能调出以下界面,选 Network git
query
的字段,这是咱们要构造的 GraphQL Query 的一个重要信息。
query
的字段相仿(由于有一点须要更改的细节)
Content-Type
是
application/graphql
,Body 中的 GraphQL 构造,参照
Request Payload 中的
query
的字段来构造
query
便可,这也是 GraphQL 的强大之处。好比咱们只想要题目的
content
信息,那么其
query
则为
query{question(titleSlug:"two-sum") {content}}
复制代码
在上边,已经利用 Postman 查询到想要的数据了,而如今咱们要作的就是用代码将上述操做展现出来。这边,使用 OkHttp 来进行题目信息获取。github
import okhttp3.*;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import java.io.IOException;
import java.util.Map;
import static java.lang.System.out;
public class Question {
public static void main(String... args) throws IOException {
String questionUrl = "https://leetcode.com/problems/two-sum/description/";
String graphqlUrl = "https://leetcode.com/graphql";
Connection.Response response = Jsoup.connect(questionUrl)
.method(Connection.Method.GET)
.execute();
Map<String,String>cookies = response.cookies();
for (Map.Entry<String,String>entry:cookies.entrySet()){
//out.println(entry.getKey() + ": " + entry.getValue());
}
String csrftoken = response.cookie("csrftoken");
String __cfduid = response.cookie("__cfduid");
OkHttpClient client = new OkHttpClient.Builder()
.followRedirects(false)
.followSslRedirects(false)
.build();
String postBody = "query{\n" +
" question(titleSlug:\"two-sum\") {\n" +
" content\n" +
" }\n" +
"}\n";
Request request = new Request.Builder()
.addHeader("Content-Type","application/graphql")
.addHeader("Referer",questionUrl)
.addHeader("Cookie","__cfduid=" + __cfduid + ";" + "csrftoken=" + csrftoken)
.addHeader("x-csrftoken",csrftoken)
.url(graphqlUrl)
.post(RequestBody.create(MediaType.parse("application/graphql; charset=utf-8"),postBody))
.build();
Response response1 = client.newCall(request).execute();
//out.println(response1.headers());
out.println(response1.body().string());
}
}
复制代码
执行结果: 后端