@soyaxell09/zenbot-scraper 1.0.12 → 1.0.13
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.
- package/package.json +2 -1
- package/src/scrapers/apk.js +67 -73
- package/src/scrapers/instagram.js +19 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soyaxell09/zenbot-scraper",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Scrapers de descarga y búsqueda para bots de WhatsApp — YouTube, TikTok, Instagram, Facebook, Twitter, Pinterest, MediaFire, GitHub, APK, Google Drive, XNXX, PornHub, XVideos, XHamster, Rule34, Screenshot y más.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"@distube/ytdl-core": "^4.16.0",
|
|
55
55
|
"axios": "^1.6.0",
|
|
56
56
|
"cheerio": "^1.0.0",
|
|
57
|
+
"node-fetch": "^3.3.2",
|
|
57
58
|
"form-data": "^4.0.0"
|
|
58
59
|
},
|
|
59
60
|
"engines": {
|
package/src/scrapers/apk.js
CHANGED
|
@@ -5,52 +5,51 @@
|
|
|
5
5
|
* Deja los créditos we 🗣️
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import axios from 'axios'
|
|
9
|
-
import * as cheerio from 'cheerio'
|
|
8
|
+
import axios from 'axios';
|
|
9
|
+
import * as cheerio from 'cheerio';
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const UA = 'Mozilla/5.0 (Linux; Android 11; Redmi Note 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36';
|
|
12
|
+
const BASE = 'https://apkpure.net';
|
|
13
|
+
const DL_BASE = 'https://d.apkpure.net';
|
|
14
|
+
const HEADERS = { 'User-Agent': UA, 'Referer': BASE };
|
|
14
15
|
|
|
15
16
|
function extractPkg(href) {
|
|
16
|
-
const m = href?.match(/\/((?:com|org|net|io|co)\.[a-z0-9.]+)(?:\/|$)/i)
|
|
17
|
-
return m ? m[1] : ''
|
|
17
|
+
const m = href?.match(/\/((?:com|org|net|io|co)\.[a-z0-9.]+)(?:\/|$)/i);
|
|
18
|
+
return m ? m[1] : '';
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return
|
|
21
|
+
function parsePageData(data) {
|
|
22
|
+
try {
|
|
23
|
+
const m = data.match(/window\.apkpure\s*=\s*\{pageData:\s*(\{.*?\})\s*[,;]/s);
|
|
24
|
+
if (m) return JSON.parse(m[1]);
|
|
25
|
+
} catch {}
|
|
26
|
+
return null;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
export async function apkSearch(query, limit = 5) {
|
|
29
|
-
if (!query?.trim()) throw new Error('Query vacío')
|
|
30
|
-
|
|
31
|
-
const $ = await searchPage(query)
|
|
32
|
-
const results = []
|
|
33
|
-
const seen = new Set()
|
|
34
|
-
|
|
35
|
-
$('.brand-info-top').each((_, el) => {
|
|
36
|
-
if (results.length >= limit) return false
|
|
30
|
+
if (!query?.trim()) throw new Error('Query vacío');
|
|
37
31
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
const { data } = await axios.get(`${BASE}/search?q=${encodeURIComponent(query)}`, {
|
|
33
|
+
headers: HEADERS, timeout: 15000
|
|
34
|
+
});
|
|
35
|
+
const $ = cheerio.load(data);
|
|
36
|
+
const results = [];
|
|
37
|
+
const seen = new Set();
|
|
42
38
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
.map(a => $(a).attr('href'))
|
|
46
|
-
.find(h => extractPkg(h)) || ''
|
|
39
|
+
$('.search-brand-container').each((_, el) => {
|
|
40
|
+
if (results.length >= limit) return false;
|
|
47
41
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
const name = $(el).find('a.top').first().text().trim();
|
|
43
|
+
const dev = $(el).find('a.developer').first().text().trim();
|
|
44
|
+
const date = $(el).find('span.time').first().text().trim();
|
|
45
|
+
const icon = $(el).find('img.app-icon-img').first().attr('data-original') || '';
|
|
46
|
+
const appHref = $(el).find('a.top').first().attr('href') || '';
|
|
47
|
+
const pkg = extractPkg(appHref);
|
|
51
48
|
|
|
52
|
-
|
|
49
|
+
if (!name || !pkg || seen.has(pkg)) return;
|
|
50
|
+
seen.add(pkg);
|
|
53
51
|
|
|
52
|
+
const appUrl = appHref.startsWith('http') ? appHref : `${BASE}${appHref}`;
|
|
54
53
|
results.push({
|
|
55
54
|
name,
|
|
56
55
|
developer: dev,
|
|
@@ -58,55 +57,50 @@ export async function apkSearch(query, limit = 5) {
|
|
|
58
57
|
date,
|
|
59
58
|
icon,
|
|
60
59
|
appUrl,
|
|
61
|
-
dlUrl:
|
|
62
|
-
})
|
|
63
|
-
})
|
|
60
|
+
dlUrl: `${DL_BASE}/b/APK/${pkg}?version=latest`,
|
|
61
|
+
});
|
|
62
|
+
});
|
|
64
63
|
|
|
65
|
-
if (!results.length) throw new Error('No se encontraron resultados')
|
|
66
|
-
return results
|
|
64
|
+
if (!results.length) throw new Error('No se encontraron resultados');
|
|
65
|
+
return results;
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
export async function apkInfo(pkgOrUrl) {
|
|
70
|
-
let pkg = pkgOrUrl
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const icon = el.closest('.search-result').find('img').first().attr('src') || ''
|
|
95
|
-
|
|
96
|
-
const dlLinks = []
|
|
97
|
-
$(`a[href*="d.apkpure.com"]`).each((_, a) => {
|
|
98
|
-
const href = $(a).attr('href') || ''
|
|
99
|
-
if (href.includes(pkg)) dlLinks.push(href)
|
|
100
|
-
})
|
|
69
|
+
let pkg = pkgOrUrl.includes('apkpure') ? extractPkg(pkgOrUrl) : pkgOrUrl;
|
|
70
|
+
if (!pkg) pkg = pkgOrUrl;
|
|
71
|
+
|
|
72
|
+
const shortName = pkg.split('.').slice(-2).join('-').toLowerCase();
|
|
73
|
+
|
|
74
|
+
const { data } = await axios.get(`${BASE}/${shortName}/${pkg}/download`, {
|
|
75
|
+
headers: HEADERS, timeout: 15000, validateStatus: () => true
|
|
76
|
+
});
|
|
77
|
+
const $ = cheerio.load(data);
|
|
78
|
+
const pageData = parsePageData(data);
|
|
79
|
+
|
|
80
|
+
const name = pageData?.versionName
|
|
81
|
+
? $('title').text().split(' APK')[0].replace('Download ', '').trim()
|
|
82
|
+
: $('h1, .title-like').first().text().trim();
|
|
83
|
+
const version = pageData?.versionName || $('[class*="version"]').first().text().trim().match(/[\d.]+/)?.[0] || '';
|
|
84
|
+
const size = $('[class*="size"]').first().text().trim();
|
|
85
|
+
const icon = $('img.icon, img[itemprop="image"]').first().attr('src') || '';
|
|
86
|
+
const dev = $('[class*="developer"], .dev-info, [itemprop="author"]').first().text().trim();
|
|
87
|
+
|
|
88
|
+
const dlLinks = [];
|
|
89
|
+
$(`a[href*="d.apkpure.net"]`).each((_, a) => {
|
|
90
|
+
const href = $(a).attr('href') || '';
|
|
91
|
+
if (href.includes(pkg)) dlLinks.push(href);
|
|
92
|
+
});
|
|
101
93
|
|
|
102
94
|
return {
|
|
103
95
|
name,
|
|
104
96
|
developer: dev,
|
|
105
97
|
pkg,
|
|
106
|
-
|
|
98
|
+
version,
|
|
99
|
+
size,
|
|
107
100
|
icon,
|
|
108
|
-
download:
|
|
101
|
+
download: `${DL_BASE}/b/APK/${pkg}?version=latest`,
|
|
102
|
+
downloadXapk: `${DL_BASE}/b/XAPK/${pkg}?version=latest`,
|
|
109
103
|
dlLinks: [...new Set(dlLinks)],
|
|
110
|
-
url:
|
|
111
|
-
}
|
|
104
|
+
url: `${BASE}/${shortName}/${pkg}`,
|
|
105
|
+
};
|
|
112
106
|
}
|
|
@@ -29,26 +29,34 @@ function parseItems(html) {
|
|
|
29
29
|
items.push({ type, url: clean });
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// Primero agregar fuentes directas (CDN Instagram)
|
|
32
33
|
$('source[src]').each((_, el) => {
|
|
33
34
|
const src = $(el).attr('src');
|
|
34
|
-
if (src) add('video', src);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
$('a[href]').each((_, el) => {
|
|
38
|
-
const href = $(el).attr('href') || '';
|
|
39
|
-
if (!href.includes('kdnsd/v1/download')) return;
|
|
40
|
-
const b64 = href.split('url=')[1] || '';
|
|
41
|
-
const decoded = decodeUrl(decodeURIComponent(b64));
|
|
42
|
-
const type = decoded.includes('.mp4') ? 'video' : 'image';
|
|
43
|
-
add(type, href.replace(/&/g, '&'));
|
|
35
|
+
if (src && !src.includes('kdnsd')) add('video', src);
|
|
44
36
|
});
|
|
45
37
|
|
|
46
38
|
$('img[src]').each((_, el) => {
|
|
47
39
|
const src = $(el).attr('src') || '';
|
|
48
|
-
if (src.includes('
|
|
40
|
+
if ((src.includes('cdninstagram') || src.includes('fbcdn')) && !src.includes('kdnsd'))
|
|
49
41
|
add('image', src);
|
|
50
42
|
});
|
|
51
43
|
|
|
44
|
+
if (!items.length) {
|
|
45
|
+
$('a[href]').each((_, el) => {
|
|
46
|
+
const href = $(el).attr('href') || '';
|
|
47
|
+
if (!href.includes('kdnsd/v1/download')) return;
|
|
48
|
+
const b64 = href.split('url=')[1] || '';
|
|
49
|
+
const decoded = decodeUrl(decodeURIComponent(b64));
|
|
50
|
+
const type = decoded.includes('.mp4') ? 'video' : 'image';
|
|
51
|
+
add(type, href.replace(/&/g, '&'));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
$('img[src]').each((_, el) => {
|
|
55
|
+
const src = $(el).attr('src') || '';
|
|
56
|
+
if (src.includes('kdnsd/v1/download')) add('image', src);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
52
60
|
return items;
|
|
53
61
|
}
|
|
54
62
|
|