mirror of
https://github.com/ION606/linkedin-api.git
synced 2026-05-14 22:06:54 +00:00
added logging
This commit is contained in:
+30
-14
@@ -3,6 +3,8 @@ import { wrapper } from 'axios-cookiejar-support';
|
|||||||
import { CookieJar } from 'tough-cookie';
|
import { CookieJar } from 'tough-cookie';
|
||||||
import axiosModule from 'axios';
|
import axiosModule from 'axios';
|
||||||
import { LinkedInProfile, Company, GenericEntity, Group, SocialActivityCounts } from '../index.js';
|
import { LinkedInProfile, Company, GenericEntity, Group, SocialActivityCounts } from '../index.js';
|
||||||
|
import { LoadingBar } from './misc.js';
|
||||||
|
|
||||||
|
|
||||||
const cookieJar = new CookieJar();
|
const cookieJar = new CookieJar();
|
||||||
const axios = wrapper(axiosModule.create({
|
const axios = wrapper(axiosModule.create({
|
||||||
@@ -187,21 +189,28 @@ export default class linkedInAPIClass {
|
|||||||
*/
|
*/
|
||||||
evade = () => wait(randomIntFromInterval(2, 5) * 1000);
|
evade = () => wait(randomIntFromInterval(2, 5) * 1000);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} keyword i.e. "biotechnology"
|
* @param {String} keyword i.e. "biotechnology"
|
||||||
* @param {Array<Number>?} numEmp
|
* @param {Array<Number>?} numEmp
|
||||||
* @param {Number?} [limit=1000] the function will use the bound the given number is contained in (see {@link findRangeIndex} for ranges)
|
* @param {Number?} [limit=1000] the function will use the bound the given number is contained in (see {@link findRangeIndex} for ranges)
|
||||||
* @param {Number?} [start=0]
|
* @param {Number?} [start=0]
|
||||||
* @param {boolean?} [castToClass=true] whether the function should return a list of Company classes or just raw JSON
|
* @param {boolean?} [castToClass=true] whether the function should return a list of Company classes or just raw JSON
|
||||||
* @param {boolean} [excludeGeneric=false]
|
* @param {boolean} [excludeGeneric=false]
|
||||||
* @returns {Promise<[SocialActivityCounts | Group | Company | GenericEntity]>}
|
* @returns {Promise<[SocialActivityCounts | Group | Company | GenericEntity]>}
|
||||||
*/
|
*/
|
||||||
async searchCompanies(keyword, numEmp = undefined, limit = 1000, start = 0, castToClass = true, excludeGeneric = false) {
|
async searchCompanies(keyword, numEmp = undefined, limit = 1000, start = 0, castToClass = true, excludeGeneric = false) {
|
||||||
const compAll = [];
|
const compAll = [];
|
||||||
|
|
||||||
|
if (this.logAll) console.log(`scanning for ${limit} companies with the keyword "${keyword}"`);
|
||||||
|
|
||||||
|
const lb = (this.logAll) ? new LoadingBar(Math.round(limit / 50)) : null;
|
||||||
|
|
||||||
for (let i = start; i < limit; i += 50) {
|
for (let i = start; i < limit; i += 50) {
|
||||||
let urlExt = `variables=(start:${i},origin:GLOBAL_SEARCH_HEADER,query:(keywords:${keyword},flagshipSearchIntent:SEARCH_SRP,queryParameters:List((key:resultType,value:List(COMPANIES))${(numEmp) ? `,(key:companySize,value:List(${numsToSizes(...numEmp)}))` : ''}),includeFiltersInResponse:false))`;
|
let urlExt = `variables=(start:${i},origin:GLOBAL_SEARCH_HEADER,query:(keywords:${keyword},flagshipSearchIntent:SEARCH_SRP,queryParameters:List((key:resultType,value:List(COMPANIES))${(numEmp) ? `,(key:companySize,value:List(${numsToSizes(...numEmp)}))` : ''}),includeFiltersInResponse:false))`;
|
||||||
const r = await this._makeReq(urlExt);
|
const r = await this._makeReq(urlExt);
|
||||||
|
|
||||||
|
if (this.logAll) lb.increment();
|
||||||
|
|
||||||
if (!r?.included && r?.data?.errors) {
|
if (!r?.included && r?.data?.errors) {
|
||||||
console.error(JSON.stringify(r.data.errors))
|
console.error(JSON.stringify(r.data.errors))
|
||||||
throw "ERROR!";
|
throw "ERROR!";
|
||||||
@@ -230,7 +239,9 @@ export default class linkedInAPIClass {
|
|||||||
* LAPI.searchEmployees("John Appleseed", 50, true, ["1418841"], [1])
|
* LAPI.searchEmployees("John Appleseed", 50, true, ["1418841"], [1])
|
||||||
*/
|
*/
|
||||||
async searchEmployees(keyword, limit = 1000, castToClass = true, filterObfuscated = true, currentCompanies = [], conDeg = []) {
|
async searchEmployees(keyword, limit = 1000, castToClass = true, filterObfuscated = true, currentCompanies = [], conDeg = []) {
|
||||||
const empAll = [];
|
const empAll = [],
|
||||||
|
lb = (this.logAll) ? new LoadingBar(Math.floor(limit/10)) : null;
|
||||||
|
|
||||||
for (let i = 0; empAll.length < limit; i += 50) {
|
for (let i = 0; empAll.length < limit; i += 50) {
|
||||||
let urlExt = `includeWebMetadata=true&variables=(start:${i},query:(keywords:${keyword},flagshipSearchIntent:SEARCH_SRP,queryParameters:List((key:resultType,value:List(PEOPLE))`;
|
let urlExt = `includeWebMetadata=true&variables=(start:${i},query:(keywords:${keyword},flagshipSearchIntent:SEARCH_SRP,queryParameters:List((key:resultType,value:List(PEOPLE))`;
|
||||||
|
|
||||||
@@ -240,6 +251,8 @@ export default class linkedInAPIClass {
|
|||||||
|
|
||||||
const r = await this._makeReq(urlExt);
|
const r = await this._makeReq(urlExt);
|
||||||
|
|
||||||
|
if (this.logAll) lb.increment(5);
|
||||||
|
|
||||||
// there's nothing left, returns what we have
|
// there's nothing left, returns what we have
|
||||||
if (!r?.included?.length) {
|
if (!r?.included?.length) {
|
||||||
if (!castToClass) return empAll;
|
if (!castToClass) return empAll;
|
||||||
@@ -281,15 +294,17 @@ export default class linkedInAPIClass {
|
|||||||
let cookie;
|
let cookie;
|
||||||
if (this.resetCookies || !fs.existsSync("cookie.txt")) {
|
if (this.resetCookies || !fs.existsSync("cookie.txt")) {
|
||||||
cookie = await this.helper.getCookies(username, password);
|
cookie = await this.helper.getCookies(username, password);
|
||||||
console.log(cookie);
|
if (this.logAll) console.log(cookie);
|
||||||
|
|
||||||
if (cookie['login_result'] != "CHALLENGE") throw `\n\nIP IS NOT AUTHORIZED, PLEASE LOG IN THROUGH YOUR BROWSER USING:\nusername: ${username}\npassword: ${password}\n\n`;
|
if (cookie['login_result'] == "CHALLENGE") throw `\n\nIP IS NOT AUTHORIZED, PLEASE LOG IN THROUGH YOUR BROWSER USING:\nusername: ${username}\npassword: ${password}\n\n`;
|
||||||
if (cookie['login_result'] != "PASS") throw cookie;
|
if (cookie['login_result'] != "PASS") throw cookie;
|
||||||
|
|
||||||
// const sessioncookie = await this.#getCookies();
|
// const sessioncookie = await this.#getCookies();
|
||||||
// throw "NO COOKIE FOUND!";
|
// throw "NO COOKIE FOUND!";
|
||||||
} else cookie = fs.readFileSync('cookie.txt');
|
} else cookie = fs.readFileSync('cookie.txt');
|
||||||
|
|
||||||
|
if (this.logAll) console.log("LOGGED IN!");
|
||||||
|
|
||||||
this.headers = {
|
this.headers = {
|
||||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0',
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0',
|
||||||
'Accept': 'application/vnd.linkedin.normalized+json+2.1',
|
'Accept': 'application/vnd.linkedin.normalized+json+2.1',
|
||||||
@@ -311,7 +326,8 @@ export default class linkedInAPIClass {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(resetCookies = false) {
|
constructor(logAll = false, resetCookies = false) {
|
||||||
|
this.logAll = logAll;
|
||||||
this.resetCookies = resetCookies;
|
this.resetCookies = resetCookies;
|
||||||
this.helper = new APIHelper();
|
this.helper = new APIHelper();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import { cursorTo } from "readline";
|
||||||
|
|
||||||
|
|
||||||
export class ReactionTypeCount {
|
export class ReactionTypeCount {
|
||||||
constructor({ count, reactionType }) {
|
constructor({ count, reactionType }) {
|
||||||
this.count = count;
|
this.count = count;
|
||||||
@@ -28,3 +31,26 @@ export class GenericEntity {
|
|||||||
Object.assign(this, data);
|
Object.assign(this, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class LoadingBar {
|
||||||
|
constructor(size) {
|
||||||
|
this.size = size;
|
||||||
|
this.cursor = 0;
|
||||||
|
this.timer = null;
|
||||||
|
|
||||||
|
cursorTo(process.stdout, this.cursor);
|
||||||
|
|
||||||
|
// draw the initial outline
|
||||||
|
process.stdout.write("\x1B[?25l");
|
||||||
|
for (let i = 0; i < this.size; i++) {
|
||||||
|
process.stdout.write("\u2591");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
increment(amt) {
|
||||||
|
cursorTo(process.stdout, this.cursor);
|
||||||
|
for (let i = 0; i < amt; i++) process.stdout.write("\u2588");
|
||||||
|
this.cursor += amt;
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+10
-4
@@ -1,17 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "linkedin-api",
|
"name": "linkedin-api-js",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0-11",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "linkedin-api",
|
"name": "linkedin-api-js",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0-11",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"axios-cookiejar-support": "^5.0.1",
|
"axios-cookiejar-support": "^5.0.1",
|
||||||
"cheerio": "^1.0.0-rc.12",
|
"cheerio": "^1.0.0-rc.12",
|
||||||
|
"readline": "^1.3.0",
|
||||||
"tough-cookie": "^4.1.3"
|
"tough-cookie": "^4.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -381,6 +382,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||||
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
|
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/readline": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg=="
|
||||||
|
},
|
||||||
"node_modules/requires-port": {
|
"node_modules/requires-port": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"axios-cookiejar-support": "^5.0.1",
|
"axios-cookiejar-support": "^5.0.1",
|
||||||
"cheerio": "^1.0.0-rc.12",
|
"cheerio": "^1.0.0-rc.12",
|
||||||
|
"readline": "^1.3.0",
|
||||||
"tough-cookie": "^4.1.3"
|
"tough-cookie": "^4.1.3"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import LinkedInAPIClass from "../index.js";
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const LAPI = new LinkedInAPIClass();
|
const LAPI = new LinkedInAPIClass(true);
|
||||||
|
|
||||||
const o = JSON.parse(fs.readFileSync('config.json'));
|
const o = JSON.parse(fs.readFileSync('config.json'));
|
||||||
await LAPI.login(o.email, o.password);
|
await LAPI.login(o.email, o.password);
|
||||||
|
|||||||
Reference in New Issue
Block a user