-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscrape.rs
95 lines (85 loc) · 3.03 KB
/
scrape.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use crate::{curl_parser, models};
use reqwest::{
header::{self, HeaderMap, HeaderName, HeaderValue},
RequestBuilder,
};
const CSRF_COOKIE: &str = "csrftoken";
const LEETCODE_SESSION_COOKIE: &str = "LEETCODE_SESSION";
const BASE_URL: &str = "https://leetcode.com/graphql/";
/// Takes the submission id and then return the request
pub fn create_scrape_request(
submission_id: u32,
) -> Result<RequestBuilder, Box<dyn std::error::Error>> {
let submission_id_string = submission_id.to_string();
let cookies = curl_parser::parse_curl();
let csrf_header = HeaderName::from_static("x-csrftoken");
let csrf_token = cookies.get(CSRF_COOKIE).unwrap(); //FIXME: raise appropriate error and panic
let session = cookies.get(LEETCODE_SESSION_COOKIE).unwrap(); //FIXME: raise appropriate error and panic
let cookie_value: HeaderValue =
format!("csrftoken={}; LEETCODE_SESSION={}", csrf_token, session)
.parse()
.unwrap();
let query = r#"query submissionDetails($submissionId: Int!) {
submissionDetails(submissionId: $submissionId) {
runtime
runtimeDisplay
runtimePercentile
runtimeDistribution
memory
memoryDisplay
memoryPercentile
memoryDistribution
code
timestamp
statusCode
user {
username
profile {
realName
userAvatar
}
}
lang {
name
verboseName
}
question {
questionId
}
notes
topicTags {
tagId
slug
name
}
runtimeError
compileError
lastTestcase
}
}"#;
let mut body = std::collections::HashMap::new();
let variables_body = &format!(" {{ \"submissionId\": {} }}", submission_id_string);
body.insert("query", query);
body.insert("variables", variables_body);
let mut headers = HeaderMap::new();
headers.insert(header::ORIGIN, "https://leetcode.com".parse().unwrap());
headers.insert(header::CONTENT_TYPE, "application/json".parse().unwrap());
headers.insert(header::USER_AGENT, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36".parse().unwrap());
headers.insert(header::COOKIE, cookie_value);
headers.insert(header::REFERER, "https://leetcode.com".parse().unwrap());
headers.insert(csrf_header, csrf_token.parse().unwrap());
let client = reqwest::Client::new();
let request = client.post(BASE_URL).headers(headers).json(&body);
Ok(request)
}
pub async fn scrape_submission(
request: RequestBuilder,
submission_id: u32,
) -> Result<models::ScrappedResponse, Box<dyn std::error::Error>> {
let resp = request.send().await.unwrap();
let submission_data = resp.json::<models::SubmissionResponse>().await?;
Ok(models::ScrappedResponse {
submission_id,
submission_data,
})
}