-
Notifications
You must be signed in to change notification settings - Fork 0
/
zarastock.js
150 lines (137 loc) · 4.4 KB
/
zarastock.js
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/**
* Web scraper for Zara.com/us
* To check for if any item is available with the sizes.
* Send email or sms to users for notification.
*/
class Scraper {
constructor(url) {
this.url = url;
this.sgMail = null;
this.accountSid = null;
this.authToken = null;
this.client = null;
this.puppeteer = null;
}
/**
* Setup the email and SMS API
* This is required for using API from @sendGrid and @TWILIO
* Look at the documentation for how to use it.
*/
setUpEmailSMS(sgMail,accountSid,authToken,client,puppeteer) {
this.sgMail = sgMail;
this.accountSid = accountSid;
this.authToken = authToken;
this.client = client;
this.puppeteer = puppeteer;
}
setLink(url) {
this.url = url;
}
sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Going to the url and grab the information.
* @returns object {name: name of the item,...itemsSize: size and its status.}
*/
async checkAvailableItem() {
var itemStatus;
try {
const browser = await this.puppeteer.launch();
const page = await browser.newPage();
await page
.goto(this.url, {
waitUntil: ["load", "domcontentloaded"],
})
.then(async () => {
const title = await page.evaluate(() => document.title);
const items = await page.evaluate(() =>
Array.from(
document.querySelectorAll(
"#main > article > div.product-detail-view__main > div.product-detail-view__side-bar > div.product-detail-info.product-detail-view__product-info > div.product-detail-size-selector.product-detail-info__size-selector.product-detail-size-selector--is-open.product-detail-size-selector--expanded > div > ul > li.product-detail-size-selector__size-list-item"
)
).map((rs) => ({
sizeName: rs.textContent.trim(),
available:
rs.className ==
"product-detail-size-selector__size-list-item product-detail-size-selector__size-list-item--is-disabled product-detail-size-selector__size-list-item--out-of-stock"
? "no"
: "yes",
}))
);
itemStatus = { name: title, ...items };
await browser.close();
});
return itemStatus;
} catch (erro) {
console.log(erro);
browser.close();
return undefined;
}
}
/**
* Send email
* @param {*} toEmail to email you want to send
* @param {*} fromEmail from email you send to.
* @param {*} subject any subject
* @param {*} body any body
* @returns
*/
sendEmail(toEmail, fromEmail, subject, body) {
const email = {
to: toEmail,
from: fromEmail,
subject: subject,
text: body,
html: body,
};
return this.sgMail.send(email);
}
/**
* Send SMS to a phone number
* @param {*} toPhoneNumber
* @param {*} fromPhoneNumber
* @param {*} body
*/
async sendSMS(toPhoneNumber, fromPhoneNumber, body) {
await this.client.messages
.create({
body: body,
from: fromPhoneNumber,
to: toPhoneNumber,
})
.then((message) => console.log("SMS sent with ID: " + message.sid));
}
/**
* This method finds any item link on the website.
* If the item is found then return the link.
* If the item is not found then return undefined.
* string name: name of the item.
* @returns string or undefined.
*/
async findItemLink(name) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://www.zara.com/us/en/search", {
waitUntil: ["load", "domcontentloaded"],
});
await page.type("#search-products-form-combo-input", search);
// console.log(i);
try {
const i = await page.waitForSelector(
"#main > article > div > div > div.search-products-view__search-results > section > ul >li >a"
);
const preloadHref = await page.$eval(
"#main > article > div > div > div.search-products-view__search-results > section > ul > li > a",
(el) => el.href
);
console.log(preloadHref);
await checkAvailable(preloadHref);
} catch (e) {
console.log("Product not found");
await browser.close();
}
await browser.close();
}
} // End class
module.exports = Scraper