This repository has been archived by the owner on Aug 9, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.ts
110 lines (85 loc) · 2.83 KB
/
index.ts
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*----------------------------------
- DEPENDANCES
----------------------------------*/
// Node.js
import request from 'request';
// Internal
import validate from './validate';
export { default as validate } from './validate';
/*----------------------------------
- TYPE
----------------------------------*/
import {
TGlobalOptions,
TAdapter,
TRequestWithExtractors,
TRequestWithBody,
TScrapeResult,
TExtractor,
ValueExtractor
} from './types';
export type { TExtractedPrice } from './types';
type TOptions = Omit<TRequestWithExtractors, 'extract' | 'url' | 'method'>;
/*----------------------------------
- VARIOUS DELCARATIONS
----------------------------------*/
const local = process.argv.includes('-local');
class ApiError extends Error {
public constructor( public code: number, message: string ) {
super(message);
}
}
const defaultAdapter: TAdapter = (options) => new Promise((resolve, reject) => request({
...options,
json: true
}, (error, response) => {
if (response && response.statusCode !== 200)
error = new ApiError( response.statusCode, response.body );
if (error) {
reject(error);
return;
}
resolve(response.body);
}));
/*----------------------------------
- SCRAPER
----------------------------------*/
export default class Scraper {
public constructor( public apiKey: string, private options: TGlobalOptions = {} ) {}
public scrape<TData extends any = any>( requests: TRequestWithExtractors[] ): Promise<TScrapeResult<TData>[]> {
const sendRequest = this.options.adapter || defaultAdapter;
return sendRequest({
method: 'POST',
url: local ? 'http://localhost:3011/v0' : 'https://scrapingapi.io/v0',
headers: {
'content-type': 'application/json',
'accepted': 'application/json',
'Authorization': this.apiKey,
},
body: {
requests: validate(requests)
},
});
}
public get<TData extends any = any>(
url: string,
options?: TOptions,
extract?: TExtractor | ValueExtractor
): Promise<TScrapeResult<TData>> {
return this.scrape<TData>([{ method: 'GET', url, extract, ...options }]).then( res => res[0] );
}
public post<TData extends any = any>(
url: string,
body: TRequestWithBody["body"],
bodyType: TRequestWithBody["bodyType"],
options?: TOptions,
extract?: TExtractor | ValueExtractor
): Promise<TScrapeResult<TData>> {
return this.scrape<TData>([{ method: 'POST', url, extract, body, bodyType, ...options }]).then( res => res[0] );
}
}
export const $ = (selector: string) => new ValueExtractor(selector)
/*module.exports = (apiKey: string) => ({
page: new Scraper(apiKey),
$: $
})*/