Compare commits
No commits in common. "93a512c9801170665a8a32561a9682ae69a9f5e9" and "ff7421fad2ac9abc9986c61e959c597880d6704b" have entirely different histories.
93a512c980
...
ff7421fad2
@ -1,207 +0,0 @@
|
|||||||
// ==UserScript==
|
|
||||||
// @name Yandex Promo Links Collector (Multi-Query Console Version)
|
|
||||||
// @namespace yandex.console.collector.promo.multi
|
|
||||||
// @version 1.2
|
|
||||||
// @description Собирает промо ссылки из выдачи Яндекса для нескольких запросов — версия для Tampermonkey (единый вывод)
|
|
||||||
// @match https://yandex.ru/search/*
|
|
||||||
// @match https://www.yandex.ru/search/*
|
|
||||||
// @match https://yandex.com/search/*
|
|
||||||
// @grant GM_xmlhttpRequest
|
|
||||||
// @connect yandex.ru
|
|
||||||
// @connect yandex.com
|
|
||||||
// @run-at document-idle
|
|
||||||
// ==/UserScript==
|
|
||||||
(function() {
|
|
||||||
'use strict';
|
|
||||||
// === НАСТРОЙКИ ===
|
|
||||||
const QUERIES = [
|
|
||||||
'купить Great Wall в Краснодаре',
|
|
||||||
'купить BYD в Краснодаре',
|
|
||||||
'купить SAIC в Краснодаре',
|
|
||||||
'купить BAIC в Краснодаре',
|
|
||||||
'купить Lifan в Краснодаре',
|
|
||||||
'купить Zotye в Краснодаре',
|
|
||||||
'купить Brilliance в Краснодаре',
|
|
||||||
'купить Hongqi в Краснодаре',
|
|
||||||
'купить Tank в Краснодаре',
|
|
||||||
'купить Lynk & Co в Краснодаре',
|
|
||||||
'купить Zeekr в Краснодаре',
|
|
||||||
'купить Nio в Краснодаре',
|
|
||||||
'купить Xpeng в Краснодаре',
|
|
||||||
'купить Li Auto в Краснодаре',
|
|
||||||
'купить Seres в Краснодаре',
|
|
||||||
'купить Aion в Краснодаре',
|
|
||||||
'купить Forthing в Краснодаре',
|
|
||||||
'купить Dayun в Краснодаре',
|
|
||||||
'купить авто с пробегом в Краснодаре',
|
|
||||||
'купить б/у автомобиль в Краснодаре',
|
|
||||||
'подержанные машины в Краснодаре',
|
|
||||||
'автосалоны с пробегом в Краснодаре',
|
|
||||||
'купить подержанный авто в Краснодаре',
|
|
||||||
'б/у Haval в Краснодаре',
|
|
||||||
'б/у Chery в Краснодаре',
|
|
||||||
'б/у Geely в Краснодаре',
|
|
||||||
'б/у Changan в Краснодаре',
|
|
||||||
'б/у Exeed в Краснодаре',
|
|
||||||
'б/у Jetour в Краснодаре',
|
|
||||||
'б/у GAC в Краснодаре',
|
|
||||||
'б/у Jaecoo в Краснодаре',
|
|
||||||
'б/у FAW в Краснодаре',
|
|
||||||
'б/у DongFeng в Краснодаре',
|
|
||||||
'б/у JAC в Краснодаре',
|
|
||||||
'б/у Kaiyi в Краснодаре',
|
|
||||||
'б/у BAIC в Краснодаре',
|
|
||||||
'б/у Lifan в Краснодаре',
|
|
||||||
'б/у Hongqi в Краснодаре',
|
|
||||||
'б/у Tank в Краснодаре',
|
|
||||||
'б/у Nio в Краснодаре',
|
|
||||||
'б/у Xpeng в Краснодаре',
|
|
||||||
'автосалоны подержанных авто в Краснодаре',
|
|
||||||
'купить машину с пробегом от дилера в Краснодаре',
|
|
||||||
'trade-in авто в Краснодаре',
|
|
||||||
'обмен авто с пробегом в Краснодаре',
|
|
||||||
'сертифицированные б/у автомобили в Краснодаре'
|
|
||||||
];
|
|
||||||
const MAX_PAGES_PER_QUERY = 3;// Макс. страниц на запрос
|
|
||||||
const PAGE_DELAY_MS = 500;// Задержка между страницами
|
|
||||||
const QUERY_DELAY_MS = 1000;// Задержка между запросами (чтобы не блочить)
|
|
||||||
// =================
|
|
||||||
var allLinks = [];
|
|
||||||
var uniqueLinks = new Set();
|
|
||||||
var baseUrl = window.location.origin;
|
|
||||||
// === ФУНКЦИИ ===
|
|
||||||
function cleanUrl(url) {
|
|
||||||
try {
|
|
||||||
var urlObj = new URL(url);
|
|
||||||
urlObj.searchParams.delete('primary_reqid');
|
|
||||||
urlObj.searchParams.delete('rnd');
|
|
||||||
urlObj.searchParams.delete('reqid');
|
|
||||||
return urlObj.toString();
|
|
||||||
} catch (e) {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function processPage(doc, queryLinks) {
|
|
||||||
var nodes = doc.querySelectorAll('li.serp-item a[href]');
|
|
||||||
var pageLinks = [];
|
|
||||||
for (var i = 0; i < nodes.length; i++) {
|
|
||||||
var href = nodes[i].getAttribute('href');
|
|
||||||
if (href && href.startsWith('https://yabs.yandex.ru')) {
|
|
||||||
var fullUrl = href.startsWith('http') ? href : baseUrl + href;
|
|
||||||
var cleanedUrl = cleanUrl(fullUrl);
|
|
||||||
if (!uniqueLinks.has(cleanedUrl)) {
|
|
||||||
uniqueLinks.add(cleanedUrl);
|
|
||||||
pageLinks.push(cleanedUrl);
|
|
||||||
queryLinks.push(cleanedUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pageLinks.length;
|
|
||||||
}
|
|
||||||
function getNextPageUrl(doc) {
|
|
||||||
var nextBtn = doc.querySelector('a.Pager-Item_type_next');
|
|
||||||
if (!nextBtn) {
|
|
||||||
nextBtn = doc.querySelector('a[aria-label="Следующая страница"]');
|
|
||||||
}
|
|
||||||
if (nextBtn) {
|
|
||||||
var href = nextBtn.getAttribute('href');
|
|
||||||
if (href) {
|
|
||||||
return href.startsWith('http') ? href : baseUrl + href;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
async function processQuery(query) {
|
|
||||||
var queryLinks = [];
|
|
||||||
var pagesProcessed = 0;
|
|
||||||
var searchUrl = `${baseUrl}/search/?text=${encodeURIComponent(query)}`;
|
|
||||||
try {
|
|
||||||
var html = await gmFetch(searchUrl);
|
|
||||||
var parser = new DOMParser();
|
|
||||||
var doc = parser.parseFromString(html, 'text/html');
|
|
||||||
processPage(doc, queryLinks);
|
|
||||||
pagesProcessed++;
|
|
||||||
var nextUrl = getNextPageUrl(doc);
|
|
||||||
while (nextUrl && pagesProcessed < MAX_PAGES_PER_QUERY) {
|
|
||||||
await new Promise(r => setTimeout(r, PAGE_DELAY_MS));
|
|
||||||
html = await gmFetch(nextUrl);
|
|
||||||
doc = parser.parseFromString(html, 'text/html');
|
|
||||||
processPage(doc, queryLinks);
|
|
||||||
pagesProcessed++;
|
|
||||||
nextUrl = getNextPageUrl(doc);
|
|
||||||
}
|
|
||||||
console.log(`[Запрос: "${query}"] Обработано страниц: ${pagesProcessed}, промо ссылок: ${queryLinks.length}`);
|
|
||||||
allLinks.push(queryLinks.join('\n'));
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`❌ Ошибка для запроса "${query}":`, error);
|
|
||||||
}
|
|
||||||
return queryLinks.length;
|
|
||||||
}
|
|
||||||
// === TAMPERMONKEY-ОБЁРТКИ ===
|
|
||||||
function gmFetch(url) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
GM_xmlhttpRequest({
|
|
||||||
method: 'GET',
|
|
||||||
url: url,
|
|
||||||
headers: {
|
|
||||||
'User-Agent': navigator.userAgent,
|
|
||||||
'Referer': baseUrl
|
|
||||||
},
|
|
||||||
onload: (response) => {
|
|
||||||
if (response.status >= 200 && response.status < 300) {
|
|
||||||
resolve(response.responseText);
|
|
||||||
} else {
|
|
||||||
reject(new Error(`HTTP ${response.status}`));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onerror: (err) => reject(err),
|
|
||||||
ontimeout: (err) => reject(new Error('Timeout'))
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function copyToClipboard(text) {
|
|
||||||
if (navigator.clipboard && window.isSecureContext) {
|
|
||||||
return navigator.clipboard.writeText(text);
|
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
try {
|
|
||||||
var textarea = document.createElement('textarea');
|
|
||||||
textarea.value = text;
|
|
||||||
textarea.style.position = 'fixed';
|
|
||||||
textarea.style.left = '-9999px';
|
|
||||||
document.body.appendChild(textarea);
|
|
||||||
textarea.focus();
|
|
||||||
textarea.select();
|
|
||||||
var success = document.execCommand('copy');
|
|
||||||
document.body.removeChild(textarea);
|
|
||||||
success ? resolve() : reject();
|
|
||||||
} catch (e) {
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// === ЗАПУСК ===
|
|
||||||
console.log(`🚀 Запуск сбора промо ссылок для ${QUERIES.length} запросов (макс. страниц на запрос: ${MAX_PAGES_PER_QUERY})...`);
|
|
||||||
(async function run() {
|
|
||||||
var totalLinks = 0;
|
|
||||||
for (let i = 0; i < QUERIES.length; i++) {
|
|
||||||
if (i > 0) await new Promise(r => setTimeout(r, QUERY_DELAY_MS));
|
|
||||||
totalLinks += await processQuery(QUERIES[i]);
|
|
||||||
}
|
|
||||||
// === ФИНАЛЬНЫЙ ВЫВОД ===
|
|
||||||
console.log('\n' + '='.repeat(50));
|
|
||||||
console.log(`✅ СБОР ЗАВЕРШЁН`);
|
|
||||||
console.log(`📄 Запросов обработано: ${QUERIES.length}`);
|
|
||||||
console.log(`🔗 Промо ссылок собрано всего: ${totalLinks}`);
|
|
||||||
console.log('='.repeat(50) + '\n');
|
|
||||||
if (totalLinks > 0) {
|
|
||||||
var outputText = allLinks.join('\n');
|
|
||||||
console.log(outputText);
|
|
||||||
await copyToClipboard(outputText);
|
|
||||||
console.log('\n✅ Все промо ссылки (с разделителями по запросам) скопированы в буфер обмена!');
|
|
||||||
console.log('💡 Нажмите Ctrl+V в любом месте для вставки');
|
|
||||||
} else {
|
|
||||||
console.log('⚠️ Промо ссылки не найдены');
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
})();
|
|
||||||
@ -7,9 +7,3 @@
|
|||||||
- Для работы укажите свой csrfToken и url
|
- Для работы укажите свой csrfToken и url
|
||||||
- Так же, дополнительно, можно указать начальное деление на чанки (numLatSplits, numLonSplits) и максимальную глубину рекурсии (maxDepth)
|
- Так же, дополнительно, можно указать начальное деление на чанки (numLatSplits, numLonSplits) и максимальную глубину рекурсии (maxDepth)
|
||||||
|
|
||||||
- [collect_promo_links](./parse/collect_promo_links.js)
|
|
||||||
- Собирает промо ссылки с поисковой выдачи яндекс
|
|
||||||
- Автоматически собирает с нескольких страниц автоматически переходя по ним. Для изменения количества обрабатываемых страниц изменить переменную (MAX_PAGES_PER_QUERY)
|
|
||||||
- Поддерживает переход по нескольким поисковым запросам указанным в (QUERIES)
|
|
||||||
- Эта версия для расширения Tampermonkey для удобной кнопки "Скопировать" после сбора
|
|
||||||
- Для запуска скрипта через Tampermonkey нужно разрешить выполнение пользовательских скриптов, путем включения режима разработчика <a href="browser://extensions/">browser://extensions/</a>
|
|
||||||
Loading…
Reference in New Issue
Block a user