Я пытаюсь выяснить, почему иногда некоторые запросы просто зависают.Я проанализировал некоторые ошибки, но время от времени он застревает .
Что он делает:
- У меня есть forEach итерациямассив доменов.
- После этого они начинают работать последовательно.
- Важно отметить, что я использую прокси-ротатор ( одиночная точка входа IP и поворот в каждом запросе ).Я знаю, что они не очень надежны, но я думаю, что есть какой-то способ просто убить запрос, если это займет более N секунд. .
Вот как выглядит код:
/**
* Asynchronously fetches the page referred to by `url`.
*
* @param {String} url - the URL of the page to be fetched
* @return {Promise} promise to a cheerio-processed page
*/
async function fetchPage(domain) {
return new Promise((resolve, reject) => {
request({
url: `https://www.google.com`,
proxy: 'http://13.82.26.121:10000',
timeout: 5000,
// The below parameters are specific to request-retry
maxAttempts: 5, // (default) try 5 times
retryDelay: 5000, // (default) wait for 5s before trying again
// retryStrategy: request.RetryStrategies.HTTPOrNetworkError, // (default) retry on 5xx or network errors
// Headers
headers: {
Host: 'www.google.com',
Referer: `https://www.similarweb.com/website/${domain}`,
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
'Upgrade-Insecure-Requests': 1,
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
Pragma: 'no-cache',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.8,es;q=0.6',
Cookie: cookie
}
}, (error, response, body) => {
if (error) {
console.log(error.code === 'ESOCKETTIMEDOUT');
// Set to `true` if the timeout was a ESOCKETTIMEDOUT
console.log(error.code === 'ETIMEDOUT');
// Set to `true` if the timeout was a connection timeout, `false` or
console.log(error.code === 'ECONNRESET');
// `undefined` otherwise.
console.log(error.connect === true);
process.exit(0);
return reject(error)
}
if (response) {
console.log('Attempts: ' + response.attempts);
}
const data = {
domain: domain,
totalVisits: '',
avgVisitDuration: '',
pagesPerVisit: '',
bounceRate: ''
}
if (!body) {
return resolve(data)
}
if (response.headers.cookie) {
cookie = response.headers['set-cookie']
fs.writeFile(file, cookie, () => {})
}
const $ = cheerio.load(body)
var totalVisits = $('[data-type="visits"] .engagementInfo-valueNumber').html();
var avgVisitDuration = $('[data-type="time"] .engagementInfo-valueNumber').html();
var pagesPerVisit = $('[data-type="ppv"] .engagementInfo-valueNumber').html();
var bounceRate = $('[data-type="bounce"] .engagementInfo-valueNumber').html();
data.totalVisits = totalVisits;
data.avgVisitDuration = avgVisitDuration;
data.pagesPerVisit = pagesPerVisit;
data.bounceRate = bounceRate;
console.log(data);
resolve(data)
})
})
}
Я пытался добавить тайм-аут в запрос и использовать другие пакеты с большим количеством функций, но мне кажется, что ничего не работает на 100%.Это всегда застревает и не выводится в консоли.
Вот как я вызываю функцию:
async function sleep(millis) {
return new Promise(resolve => setTimeout(resolve, millis));
}
async function run() {
const domains = await fetchUrls(INITIAL_URL);
for (const domain of domains[0]) {
await sleep(1000);
console.log("Fetching: " + domain);
const $ = await fetchPage(domain);
// do stuff with cheerio-processed page
}
return
}
run();