爬取LeetCode题目——如何发送GraphQL Query获取数据
前言
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 语言为载体的 GraphQL 的话,一大部分搜索结果都是介绍使用 graphql-java 来搭建查询服务,而我们的目的是利用 GraphQL 来获取想要的数据,并非自己搭建一个查询服务,因此如果一开始就选错了工具,就会导致后面的方向都是错误的。
以 LeetCode 第一题 1.Two Sum 为例,获取其后端发送过来的数据。利用 F12 功能调出如下界面,选 Network

找到 graphql 文件(有好多 graphql 文件,可以依次点击查找自己想要的那个,这里找到包含有题目信息的),从 preview 中我们可以看到 data 返回了题目相关的信息

那么,如何构造 GraphQL Query 来获取信息呢?从 Header 中的 Request Payload 中我们可以看到一个query的字段,这是我们要构造的 GraphQL Query 的一个重要信息。

我们并不一开始就用代码来获取题目信息,而是先利用 Postman 来看看如何获取题目信息。右键 Network 下的 graphql 文件—>Copy—>Copy as cURL(bash),如下图所示:

之后,打开 Postman—>左上角Import—>Paste Raw Text粘贴,从 Body中可以看到,构造好了的 GraphQL Query 与我们在 Request Payload 中看到的 query 的字段相仿(因为有一点需要更改的细节)

当然,如果不想直接粘贴复制的 cURL,那么我们可以自己在 Postman 中写 Header 和 Body,需要注意的是这边的 Content-Type是application/graphql,Body 中的 GraphQL 构造,参照 Request Payload 中的query的字段来构造

获取到的结果如下:

我们在实际中,可能并不需要提供的所有信息,只想要某一部分,那么只需更改query即可,这也是 GraphQL 的强大之处。比如我们只想要题目的content信息,那么其query则为
query{question(titleSlug:"two-sum") {content}}
代码
在上边,已经利用 Postman 查询到想要的数据了,而现在我们要做的就是用代码将上述操作展示出来。这边,使用 OkHttp 来进行题目信息获取。
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());
}
}
执行结果:

爬取LeetCode题目——如何发送GraphQL Query获取数据的更多相关文章
- Python爬取网上车市[http://www.cheshi.com/]的数据
#coding:utf8 #爬取网上车市[http://www.cheshi.com/]的数据 import requests, json, time, re, os, sys, time,urlli ...
- 16 react 发送异步请求获取数据 和 使用Redux-thunk中间件进行 ajax 请求发送
1.发送异步请求获取数据 1.引入 axios ( 使用 yarn add axios 进行安装 ) import axios from 'axios'; 2. 模拟 在元素完成挂载后加载数据 并初始 ...
- 我不就是吃点肉,应该没事吧——爬取一座城市里的烤肉店数据(附完整Python爬虫代码)
写在前面的一点屁话: 对于肉食主义者,吃肉简直幸福感爆棚!特别是烤肉,看着一块块肉慢慢变熟,听着烤盘上"滋滋"的声响,这种期待感是任何其他食物都无法带来的.如果说甜点是" ...
- python爬取返利网中值得买中的数据
先使用以前的方法将返利网的数据爬取下来,scrapy框架还不熟练,明日再战scrapy 查找目标数据使用的是beautifulsoup模块. 1.观察网页,寻找规律 打开值得买这块内容 1>分析 ...
- selenium跳过webdriver检测并爬取淘宝我已购买的宝贝数据
简介 上一个博文已经讲述了如何使用selenium跳过webdriver检测并爬取天猫商品数据,所以在此不再详细讲,有需要思路的可以查看另外一篇博文. 源代码 # -*- coding: utf-8 ...
- 猫眼电影爬取(三):requests+pyquery,并将数据存储到mysql数据库
还是以猫眼电影为例,这次用pyquery库进行爬取 1.简单demo,看看如何使用pyquery提取信息,并将提取到的数据进行组合 # coding: utf-8 # author: hmk impo ...
- 猫眼电影爬取(二):requests+beautifulsoup,并将数据存储到mysql数据库
上一篇通过requests+正则爬取了猫眼电影榜单,这次通过requests+beautifulsoup再爬取一次(其实这个网站更适合使用beautifulsoup库爬取) 1.先分析网页源码 可以看 ...
- 猫眼电影爬取(一):requests+正则,并将数据存储到mysql数据库
前面讲了如何通过pymysql操作数据库,这次写一个爬虫来提取信息,并将数据存储到mysql数据库 1.爬取目标 爬取猫眼电影TOP100榜单 要提取的信息包括:电影排名.电影名称.上映时间.分数 2 ...
- 【scrapy实践】_爬取安居客_广州_新楼盘数据
需求:爬取[安居客—广州—新楼盘]的数据,具体到每个楼盘的详情页的若干字段. 难点:楼盘类型各式各样:住宅 别墅 商住 商铺 写字楼,不同楼盘字段的名称不一样.然后同一种类型,比如住宅,又分为不同的情 ...
随机推荐
- 在python里使用WriteProcessMemory修改内存地址上的值
import os import sys from ctypes import * windll.kernel32.WriteProcessMemory.argtypes = [c_void_p, c ...
- oracle partition 分区
--范围分区create table person( id int, name varchar2(20), birth date, sex char(2))partition by range (bi ...
- 九、爬虫框架之Scrapy
爬虫框架之Scrapy 一.介绍 二.安装 三.命令行工具 四.项目结构以及爬虫应用简介 五.Spiders 六.Selectors 七.Items 八.Item Pipelin 九. Dowload ...
- Docker MongoDB 部署
docker search mongo 命令来查看可用版本: $ docker search mongo NAME DESCRIPTION STARS OFFICIAL AUTOMATED mongo ...
- Docker(2)--Centos7 上安装部署
Centos7 上安装docker Docker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE. 社区版是免费提供给个人开发者和小型团体使用的,企业版会提供额外的收费服务,比 ...
- ERROR 1040 (08004): Too many connections
ERROR 1040 (08004): Too many connections 长期一来,mysql低版本中,当面对连接数陡增而出现too many connections时,往往比较棘手.今天特意 ...
- 【Leetcode】二叉树的层次遍历
题目: 给定一个二叉树,返回其节点值自底向上的层次遍历. (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 例如: 思路:采用宽度优先搜索. 时间复杂度:O(n).n为节点的数量,遍历所有节 ...
- 小程序的image图片显示
最近接触到了一点小程序的东西,跟我们平常的HTML还真不太一样,这里我先大概讲一下图片的显示问题, 小程序的图片用的是<image><image/>标签,他默认的大小是宽300 ...
- 【canvas学习笔记三】样式和颜色
上一节我们学习了如何用路径绘制各种形状,但我们只能用默认的颜色和线条.这节就来学习设置不同的颜色和线条样式. 颜色 设置颜色主要有两个属性: fillStyle = color 设置填充颜色 stro ...
- Spring Boot教程(十)异步方法测试
测试 测试代码如下: @Component public class AppRunner implements CommandLineRunner { private static final Log ...