diff --git a/background.js b/background.js new file mode 100644 index 0000000..f784431 --- /dev/null +++ b/background.js @@ -0,0 +1,102 @@ +let jobs = []; +let start = false; + +const saveObjectInlocalStorage = async function (obj) { + return new Promise((resolve, reject) => { + try { + chrome.storage.local.set({ jobs: obj }); + } catch (ex) { + reject(ex); + } + }); +}; + +const getObjectInlocalStorage = async function (obj) { + return new Promise((resolve, reject) => { + try { + chrome.storage.local.get(obj, function (value) { + resolve(value); + }); + } catch (ex) { + reject(ex); + } + }); +}; + +function addPageToURL(url) { + const regex = /page=(\d+)/; + const match = url.match(regex); + const page = (match && match[1]) || "1"; + const newPage = parseInt(page) + 1; + if (!match) { + return url + `&page=${newPage}`; + } + return url.replace(regex, `page=${newPage}`); +} + +async function changeTabToNextPage(url, tabid) { + const newURL = addPageToURL(url); + await chrome.tabs.update(tabid, { url: newURL }); +} + +const filterJobsByCity = (jobs) => { + const newJobs = {}; + jobs.forEach(({ city, salary }) => { + if (!newJobs[city]) { + newJobs[city] = {}; + } + if (newJobs[city][salary]) { + newJobs[city][salary] += 1; + } else { + newJobs[city][salary] = 1; + } + }); + return newJobs; +}; + +chrome.runtime.onConnect.addListener(function (port) { + port.onMessage.addListener(async function (params, sender) { + const { cmd } = params; + if (cmd === "start") { + jobs = []; + start = true; + const [tab] = await chrome.tabs.query({ + active: true, + currentWindow: true, + }); + let port = chrome.tabs.connect(tab.id, { + name: "backgroud-content_script", + }); + port.postMessage({ cmd: "scrap" }); + } + if (cmd === "online") { + const { + sender: { + tab: { id }, + }, + } = sender; + if (start) { + let port = chrome.tabs.connect(id, { + name: "backgroud-content_script", + }); + port.postMessage({ cmd: "scrap" }); + } + } + if (cmd === "getInfo") { + const { jobsInformation, nextPage } = params; + jobs = [...jobs, ...jobsInformation]; + if (nextPage) { + const { + sender: { + tab: { url, id }, + }, + } = sender; + changeTabToNextPage(url, id); + } else { + start = false; + saveObjectInlocalStorage(filterJobsByCity(jobs)); + port.postMessage({ cmd: "finish", data: filterJobsByCity(jobs) }); + } + } + }); +}); diff --git a/contentscript.js b/contentscript.js new file mode 100644 index 0000000..8084fc3 --- /dev/null +++ b/contentscript.js @@ -0,0 +1,75 @@ +console.log("Ejecutandose el content script 1.0"); + +function getJobInformation() { + const jobs = Array.from(document.querySelectorAll("[id*='jobcard-']")); + const getJobs = jobs.map((job) => { + const [ + { href: link }, + { + children: [ + { + children: [ + { innerText: date }, + { innerText: title }, + { innerText: salary }, + { innerText: beneficios }, + { + children: [elementEnterpriseCity], + }, + ] = null, + } = {}, + ] = null, + }, + ] = job.children; + + const enterprise = elementEnterpriseCity?.querySelector("label")?.innerText; + const city = elementEnterpriseCity?.querySelector("p")?.innerText; + + return { + link, + date, + title, + salary, + beneficios, + enterprise, + city, + }; + }); + + return getJobs; +} + +function filterJobs(jobs) { + const JobsFilterBySalaryAndCity = jobs.filter((job) => { + return job.salary.toString().search(/[\d]/) >= 0 && job.city; + }); + + return JobsFilterBySalaryAndCity; +} + +const portBackground = chrome.runtime.connect({ name: "content-background" }); + +portBackground.postMessage({ cmd: "online" }); + +chrome.runtime.onConnect.addListener(function (port) { + port.onMessage.addListener(({ cmd }) => { + if (cmd === "scrap") { + const jobsInformation = getJobInformation(); + const buttonNext = document.querySelector("[class*=next]"); + const nextPage = !buttonNext.className.includes("disable"); + + portBackground.postMessage({ + cmd: "getInfo", + jobsInformation: filterJobs(jobsInformation), + nextPage, + }); + } + }); +}); + +const port = chrome.runtime.connect({ name: "contenct-popup" }); +portBackground.onMessage.addListener(async ({ cmd, data }) => { + if (cmd === "finish") { + port.postMessage({ cmd, data }); + } +}); diff --git a/images/icon.png b/images/icon.png new file mode 100644 index 0000000..1467a96 Binary files /dev/null and b/images/icon.png differ diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..25d0143 --- /dev/null +++ b/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "scraping-occ", + "description": "Obtener avisos", + "manifest_version": 3, + "version": "1.0", + "permissions": ["activeTab", "scripting", "tabs", "storage"], + "background": { + "service_worker": "background.js", + "type": "module" + }, + "content_scripts": [ + { + "matches": ["https://www.occ.com.mx/*"], + "js": ["./contentscript.js"] + } + ], + "action": { + "default_popup": "./popup/index.html" + }, + "icons": { + "32": "./images/icon.png" + } +} diff --git a/popup/index.html b/popup/index.html new file mode 100644 index 0000000..2f86fa0 --- /dev/null +++ b/popup/index.html @@ -0,0 +1,17 @@ + + +
+ + + +Obteniendo trabajos...
+