vlr-stats-scraper 1.4.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,128 +1,127 @@
1
- import * as cheerio from 'cheerio'
2
- import { Hyperbrowser } from "@hyperbrowser/sdk"
3
- import { config } from "dotenv"
4
-
5
- config()
6
-
7
- let client;
8
- function getClient() {
9
- if (!client) {
10
- client = new Hyperbrowser({
11
- apiKey: process.env.HYPERBROWSER_API_KEY,
12
- })
13
- }
14
- return client;
15
- }
16
-
17
- async function scrapePlayer(url, region) {
18
- // console.log('scrapePlayer ran')
19
- try {
20
- const scrapeData = await getClient().scrape.startAndWait({
21
- url: url,
22
- scrapeOptions: {
23
- formats: ["html"]
24
- }
25
- })
26
-
27
- const $ = cheerio.load(scrapeData.data.html);
28
- const agentsPlayed = findAgents($)
29
-
30
- return {
31
- name: getPlayerName(url),
32
- team: getCurTeam($),
33
- past_teams: getPastTeam($),
34
- winnings: getWinnings($),
35
- most_played_agents: agentsPlayed.map(data => data.Agent),
36
- avg_kda: agentsPlayed.reduce((acc, data) => acc + (parseFloat(data['K:D'])) / agentsPlayed.length, 0).toFixed(2),
37
- nationality: getNationality($),
38
- region: region,
39
- stats: agentsPlayed
40
- }
41
- }
42
- catch (error) {
43
- console.error("Error scraping website:", error);
44
- }
45
- }
46
-
47
- // testing
48
- /*
49
- node scripts/player-info-scraper.mjs
50
- */
51
-
52
- scrapePlayer("https://www.vlr.gg/player/939/mwzera/?timespan=all", "AMER")
53
-
54
-
55
- function getPlayerName(link) {
56
- let name = new URL(link).pathname.split('/').filter(ele => ele !== '').pop()
57
- return name
58
- }
59
-
60
- function findAgents($) {
61
- // console.log('findAgents ran')
62
- const header = $('.mod-agent-rows').first().children().first()
63
-
64
- const statCategories = header.text().split('\n').map(ele => ele.trim()).filter(ele => ele !== '')
65
- statCategories.unshift('Agent')
66
-
67
- const agentStats = header.next().children()
68
- const agents = agentStats.map((i, el) => {
69
- el = $(el)
70
- // console.log('agent found:', el.children().first().find('img').attr('alt'))?.trim()
71
- return {
72
- agent: el.children().first().find('img').attr('alt')?.trim(),
73
- stats: el.text().split('\t').map(ele => ele.trim()).filter(ele => ele !== '')
74
- }
75
- }).get()
76
-
77
- const agentData = agents.map(agent => {
78
- return statCategories.reduce((acc, category, index) => {
79
- if(index == 0) {
80
- acc[category] = agent.agent
81
- }
82
- else {
83
- acc[category] = agent.stats[index-1]
84
- }
85
- return acc
86
- }, {})
87
- })
88
-
89
- return agentData.length<3 ? agentData : agentData.slice(0,3)
90
- }
91
-
92
- function getCurTeam($) {
93
- // console.log('getCurTeam ran')
94
- const currentTeam = $('h2:contains("Current Teams")').first().next().text().trim()
95
- const currentTeamName = currentTeam.split('\t').filter(ele => ele.trim() !== '')
96
- // Free agents have no current team
97
- return currentTeamName.length ? currentTeamName[0].trim() : null
98
- }
99
-
100
- function getPastTeam($) {
101
- // console.log('getPastTeam ran')
102
- const pastTeams = $('h2:contains("Past Teams")').first().next().text().trim()
103
- const pastTeamNames = pastTeams.split('\t').filter(ele => ele.trim() !== ''
104
- && !ele.includes('joined')
105
- && !ele.includes(' – ')
106
- && !ele.includes('left'))
107
- .map(ele => ele.trim())
108
- return pastTeamNames
109
- }
110
-
111
- function getWinnings($) {
112
- // console.log('getWinnings ran')
113
- const events = $('h2:contains("Event Placements")').first().next()
114
- const winnings = events.children().first().text().trim()
115
- // // console.log(winnings.split('\t').map(ele => ele.trim()).filter(ele => ele !== '')[1])
116
- return winnings.split('\t').map(ele => ele.trim()).filter(ele => ele !== '')[1]
117
-
118
- }
119
-
120
- function getNationality($) {
121
- // console.log('getNationality ran')
122
- const header = $('.flag').first()
123
- // console.log('flags found:', $('.flag').length);
124
- // console.log(header.parent().text().trim())
125
- return header.parent().text().trim()
126
- }
127
-
1
+ import * as cheerio from 'cheerio'
2
+ import { Hyperbrowser } from "@hyperbrowser/sdk"
3
+ import { config } from "dotenv"
4
+
5
+ config()
6
+
7
+ let client;
8
+ function getClient() {
9
+ if (!client) {
10
+ client = new Hyperbrowser({
11
+ apiKey: process.env.HYPERBROWSER_API_KEY,
12
+ })
13
+ }
14
+ return client;
15
+ }
16
+
17
+ async function scrapePlayer(url, region) {
18
+ // console.log('scrapePlayer ran')
19
+ try {
20
+ const scrapeData = await getClient().scrape.startAndWait({
21
+ url: url,
22
+ scrapeOptions: {
23
+ formats: ["html"]
24
+ }
25
+ })
26
+
27
+ const $ = cheerio.load(scrapeData.data.html)
28
+ const agentsPlayed = findAgents($)
29
+
30
+ return {
31
+ name: getPlayerName(url),
32
+ team: getCurTeam($),
33
+ past_teams: getPastTeam($),
34
+ winnings: getWinnings($),
35
+ most_played_agents: agentsPlayed.map(data => data.Agent),
36
+ avg_kda: agentsPlayed.reduce((acc, data) => acc + (parseFloat(data['K:D'])) / agentsPlayed.length, 0).toFixed(2),
37
+ nationality: getNationality($),
38
+ region: region,
39
+ stats: agentsPlayed
40
+ }
41
+ }
42
+ catch (error) {
43
+ console.error("Error scraping website:", error);
44
+ }
45
+ }
46
+
47
+ // testing
48
+ /*
49
+ node scripts/player-info-scraper.mjs
50
+ scrapePlayer("https://www.vlr.gg/player/939/mwzera/?timespan=all", "AMER")
51
+ */
52
+
53
+
54
+ function getPlayerName(link) {
55
+ let name = new URL(link).pathname.split('/').filter(ele => ele !== '').pop()
56
+ return name
57
+ }
58
+
59
+ function findAgents($) {
60
+ // console.log('findAgents ran')
61
+ const header = $('.mod-agent-rows').first().children().first()
62
+
63
+ const statCategories = header.text().split('\n').map(ele => ele.trim()).filter(ele => ele !== '')
64
+ statCategories.unshift('Agent')
65
+
66
+ const agentStats = header.next().children()
67
+ const agents = agentStats.map((i, el) => {
68
+ el = $(el)
69
+ // console.log('agent found:', el.children().first().find('img').attr('alt'))?.trim()
70
+ return {
71
+ agent: el.children().first().find('img').attr('alt')?.trim(),
72
+ stats: el.text().split('\t').map(ele => ele.trim()).filter(ele => ele !== '')
73
+ }
74
+ }).get()
75
+
76
+ const agentData = agents.map(agent => {
77
+ return statCategories.reduce((acc, category, index) => {
78
+ if(index == 0) {
79
+ acc[category] = agent.agent
80
+ }
81
+ else {
82
+ acc[category] = agent.stats[index-1]
83
+ }
84
+ return acc
85
+ }, {})
86
+ })
87
+
88
+ return agentData.length<3 ? agentData : agentData.slice(0,3)
89
+ }
90
+
91
+ function getCurTeam($) {
92
+ // console.log('getCurTeam ran')
93
+ const currentTeam = $('h2:contains("Current Teams")').first().next().text().trim()
94
+ const currentTeamName = currentTeam.split('\t').filter(ele => ele.trim() !== '')
95
+ // Free agents have no current team
96
+ return currentTeamName.length ? currentTeamName[0].trim() : null
97
+ }
98
+
99
+ function getPastTeam($) {
100
+ // console.log('getPastTeam ran')
101
+ const pastTeams = $('h2:contains("Past Teams")').first().next().text().trim()
102
+ const pastTeamNames = pastTeams.split('\t').filter(ele => ele.trim() !== ''
103
+ && !ele.includes('joined')
104
+ && !ele.includes(' – ')
105
+ && !ele.includes('left'))
106
+ .map(ele => ele.trim())
107
+ return pastTeamNames
108
+ }
109
+
110
+ function getWinnings($) {
111
+ // console.log('getWinnings ran')
112
+ const events = $('h2:contains("Event Placements")').first().next()
113
+ const winnings = events.children().first().text().trim()
114
+ // // console.log(winnings.split('\t').map(ele => ele.trim()).filter(ele => ele !== '')[1])
115
+ return winnings.split('\t').map(ele => ele.trim()).filter(ele => ele !== '')[1]
116
+
117
+ }
118
+
119
+ function getNationality($) {
120
+ // console.log('getNationality ran')
121
+ const header = $('.flag').first()
122
+ // console.log('flags found:', $('.flag').length);
123
+ // console.log(header.parent().text().trim())
124
+ return header.parent().text().trim()
125
+ }
126
+
128
127
  export default scrapePlayer
@@ -1,3 +1,4 @@
1
+ import * as cheerio from 'cheerio'
1
2
  import { Hyperbrowser } from "@hyperbrowser/sdk"
2
3
  import { config } from "dotenv";
3
4
 
@@ -19,24 +20,50 @@ async function scrapeWebsite(url) {
19
20
  url: url,
20
21
  scrapeOptions: {
21
22
  formats: ["html"],
22
- includeTags: [".event-team-players-item"]
23
+ includeTags: [".event-header-main-title", ".event-team-players-item"]
23
24
  },
24
25
  })
26
+ const data = scrapeData.data.html
27
+ const $ = cheerio.load(data)
25
28
 
26
- const players = scrapeData.data.html.split('\n').filter(line => line.includes('event-team-players-item'))
27
- const playerLinks = players.map(player => {
28
- const match = player.match(/href="(https:\/\/www\.vlr\.gg\/player\/[^"]*)"/)
29
- return match ? match[1] + "/?timespan=all" : null;
30
- }).filter(link => link !== null);
31
-
32
- return playerLinks
29
+ /*
30
+ <h1 class="event-header-main-title">
31
+ VCT 2027: America Kickoff - North America Open Qualifier
32
+ </h1>
33
+ */
34
+ const playerLinks = $('.event-team-players-item')
35
+ .map((i, el) => $(el).attr('href'))
36
+ .get()
37
+ .filter(href => href.includes('/player/'))
38
+ .map(href => href + '/?timespan=all')
39
+
40
+ let region = $('.event-header-main-title').first().text().trim()
41
+ console.log(region)
42
+
43
+ if (region.includes('America')) {
44
+ region = 'AMER'
45
+ }
46
+ else if (region.includes('EMEA')) {
47
+ region = 'EMEA'
48
+ }
49
+ else if (region.includes('Pacific')) {
50
+ region = 'PAC'
51
+ }
52
+ else if (region.includes('China')) {
53
+ region = 'CN'
54
+ }
55
+ else {
56
+ region = null
57
+ }
58
+
59
+ return { playerLinks, region }
33
60
  }
34
61
  catch (error) {
35
62
  console.error("Error scraping website:", error)
36
63
  }
37
64
  }
38
65
 
39
- export { scrapeWebsite };
66
+ export { scrapeWebsite }
40
67
  /*
41
68
  node teamscraper.mjs
42
69
  */