-
Notifications
You must be signed in to change notification settings - Fork 0
/
webscrape-strava.ts
100 lines (85 loc) · 3.69 KB
/
webscrape-strava.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
import puppeteer, { Page } from 'puppeteer';
import { Run } from './webscrape-r2w';
import fs from 'fs';
const openBrowser = false;
const closeBrowser = true;
const email = '[email protected]';
const password = 'Whirlp00l';
const stravaLogin = async (newPage: Page) => {
await newPage.goto('https://strava.com/login');
await Promise.all([
newPage.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 }),
newPage.click('a[class="btn btn-block fb-button"]'),
]);
await newPage.type('#email', email, {delay: 100});
await newPage.type('#pass', password, {delay: 100});
await Promise.all([
newPage.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 }),
newPage.click('#loginbutton'),
]);
};
const uploadRuns = async (page: Page, runs: Run[]) => {
for (let i = 148; i < runs.length; i++) {
const run = runs[i];
await page.waitForSelector('a[href="/upload/manual"]'),
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 }),
page.$eval('a[href="/upload/manual"]', (a) => a.click()),
]);
if (run.distance === 0 || run.distance === null) {
await page.type('#activity_distance', '0.01');
}
else {
await page.type('#activity_distance', run.distance.toString());
}
await page.$eval('#distance-unit-dd div[class="selection"]',
(elem, run) => elem.innerText = run.distanceUnit.toString().toLowerCase(), run);
if (run.timeHours !== undefined) {
await page.$eval('#activity_elapsed_time_hours',
(elem, run) => (elem as HTMLInputElement).value = run.timeHours!.toString(), run);
}
if (run.timeMinutes !== undefined) {
await page.$eval('#activity_elapsed_time_minutes',
(elem, run) => (elem as HTMLInputElement).value = run.timeMinutes!.toString(), run);
}
if (run.timeSeconds !== undefined) {
await page.$eval('#activity_elapsed_time_seconds',
(elem, run) => (elem as HTMLInputElement).value = run.timeSeconds!.toString(), run);
}
await page.$eval('#activity_start_date', (elem, month, day, year) => {
(elem as HTMLInputElement).value = `${month}/${day}/${year}`;
}, run.date.getMonth() + 1, run.date.getDate(), run.date.getFullYear());
if (run.comments !== undefined) {
await page.$eval('input[name="activity[description]"]',
(elem, run) => (elem as HTMLInputElement).value = run.comments!, run);
}
await page.type('#activity_name', 'Running2win Import');
await page.$eval('#activity_name',
(elem) => (elem as HTMLInputElement).value = 'Running2win Import');
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 }),
page.click('input[value="Create"]'),
]);
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 }),
page.goto('https://strava.com/dashboard'),
]);
console.log(`Uploaded run ${i + 1}/${runs.length}`);
}
};
const webscrape = async () => {
const data = fs.readFileSync('webscrape-r2w.json');
const runs: Run[] = (JSON.parse(data.toString()) as Run[]).map((run) => {
let copy = run;
copy.date = new Date(run.date);
return copy;
});
const browser = await puppeteer.launch({headless: !openBrowser});
const page = await browser.newPage();
await stravaLogin(page);
await uploadRuns(page, runs);
if (closeBrowser) {
await browser.close();
}
};
await webscrape();