Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 19.11.2018, 00:25
Новичок на форуме
Отправить личное сообщение для mystica Посмотреть профиль Найти все сообщения от mystica
 
Регистрация: 18.11.2018
Сообщений: 8

Как реализовать многопоточный парсинг node.js
Доброго времени суток, пишу парсер инстаграма на node.js с использованием приватного апи, работаю второй день с node.js , поэтому есть вопросы. На данный момент есть рабочая однопоточная версия с прокси:

'use strict';
var InstagramPrivateAPI = {};

InstagramPrivateAPI = {};
InstagramPrivateAPI.V1 = require(__dirname + '/client/v1');
InstagramPrivateAPI.Helpers = require(__dirname + '/helpers');
var acc = require(__dirname + "/client/v1/account");
var med = require(__dirname + "/client/v1/media")

var Promise = require('../bluebird');
var _ = require('../lodash/');

module.exports = InstagramPrivateAPI;

var Client = require('instagram-private-api').V1;
var device = new Client.Device('maksgmn');
var storage = new Client.CookieFileStorage(__dirname + '/cookies/maksgmn.json');
var session = new Client.Session(device, storage);

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

var fs = require('fs');
var proxyArray = fs.readFileSync('proxy.txt').toString().split("\n");
var usernamesArray = fs.readFileSync('usernames.txt').toString().split("\n");

var proxy = "http://" + proxyArray[getRandomInt(0,proxyArray.length)]
var username = usernamesArray[getRandomInt(0,usernamesArray.length)]

console.log(proxy)
console.log(username)

Client.Request.setProxy(proxy);


acc.searchForUser(session, username) //поиск id пользователя
    .then(function(profile) {
        return profile.id
    })
    .then(function(someId) {  //получение промиса lenta
        var feed = new Client.Feed.UserMedia(session, someId);
        var lenta = Promise.mapSeries(_.range(0, 1), function() {
            return feed.get();
        }).then(function(lenta) {
        	return {id: someId, fd : lenta}
        })
        return lenta
    })
    .then(function(results) {  //обработка промиса и получение ленты пользователя
        // result should be Media[][]
        var media1 = _.flatten(results.fd);
        var urls1 = _.map(media1, function(medium) {
                //var arr1 = medium.params.images[0].url;
            var arr1 = []

            try {
                arr1 = medium.params.images[0].url
            } catch (err) {
                //console.log("lala")
            }

            return arr1;
            //console.log(medium.params.carouselMedia.images[0].url)
        })

        //console.log(urls1)

        return {id : results.id, linksNoCarousel : urls1, med : media1}
    })
    .then(function(res){

        var urls2 = _.map(res.med, function(medium) {

            var arr2 = []

            try {
                arr2 = medium.params.images[0][0].url
                //console.log(arr2)
            } catch (err) {

            }
            return arr2        
        })

        for (var i = 0; i < 5; i++) {
            if (typeof res.linksNoCarousel[i] == "undefined")
                res.linksNoCarousel[i] = urls2[i];
        }

        var arr3 = []

        for (var i = 0; i < 5; i++) {
            arr3[i] = res.linksNoCarousel[i]
        }

        return {id : res.id, links : arr3}

    })
    .then(function(mediaAndId) {
    	acc = acc.getById(session, mediaAndId.id)
    		.then(function(account) {
    			//console.log(account.params)
    			let avatar = account.params.profilePicUrl;
    			let fullName = account.params.fullName;
    			let bio = account.params.biography;
    			let media0 = mediaAndId.links[0];
    			let media1 = mediaAndId.links[1];
    			let media2 = mediaAndId.links[2];
    			let media3 = mediaAndId.links[3];
    			let media4 = mediaAndId.links[4];

    			console.log(avatar);
    			console.log(fullName);
    			console.log(bio);
    			console.log(media0);
    			console.log(media1);
    			console.log(media2);
    			console.log(media3);
    			console.log(media4);
    		})
    })


Хотелось бы, чтобы все это работало в многопотоке, иначе скорость парсинга будет очень низкая. Как это можно реализовать?
Ответить с цитированием
  #2 (permalink)  
Старый 19.11.2018, 11:16
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Сообщение от mystica
скорость парсинга будет очень низкая
если тормоза именно в парсинге (в процессорных вычислениях), то вот
https://nodejs.org/dist/latest-v10.x...r_threads.html

ну и подумать о том, как оптимизировать. Там реально большие объемы данных обсчитываются?
Ответить с цитированием
  #3 (permalink)  
Старый 19.11.2018, 12:08
Новичок на форуме
Отправить личное сообщение для mystica Посмотреть профиль Найти все сообщения от mystica
 
Регистрация: 18.11.2018
Сообщений: 8

Да в целом хорошая скорость, я не работал до этого с асинхронными функциями запустил в цикле и он профилей 100 за 5 секунд обработал, упирается в лимит запросов апи. Хотел уточнить еще: у меня конечный код выглядит примерно так:

'use strict';
var InstagramPrivateAPI = {};

InstagramPrivateAPI = {};
InstagramPrivateAPI.V1 = require(__dirname + '/client/v1');
InstagramPrivateAPI.Helpers = require(__dirname + '/helpers');
var acc = require(__dirname + "/client/v1/account");
var med = require(__dirname + "/client/v1/media")

var Promise = require('../bluebird');
var _ = require('../lodash/');

module.exports = InstagramPrivateAPI;

var Client = require('instagram-private-api').V1;
var device = new Client.Device('maksgmn');
var storage = new Client.CookieFileStorage(__dirname + '/cookies/maksgmn.json');
var session = new Client.Session(device, storage);

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

var fs = require('fs');
var proxyArray = fs.readFileSync('proxy.txt').toString().split("\n");
var usernamesArray = fs.readFileSync('usernames.txt').toString().split("\n");

var proxy = "http://" + proxyArray[getRandomInt(0,proxyArray.length)]
var username = usernamesArray[getRandomInt(0,usernamesArray.length)]

console.log(proxy)
console.log(username)

//Client.Request.setProxy(proxy);

for (var i = 0; i < usernamesArray.length; i++) {

    proxy = "http://" + proxyArray[getRandomInt(0,proxyArray.length)];
    Client.Request.setProxy(proxy);

acc.searchForUser(session, usernamesArray[i]) //поиск id пользователя
    .then(function(profile) {
        return profile.id
    })
    .then(function(someId) {  //получение промиса lenta
        var feed = new Client.Feed.UserMedia(session, someId);
        var lenta = Promise.mapSeries(_.range(0, 1), function() {
            return feed.get();
        }).then(function(lenta) {
        	return {id: someId, fd : lenta}
        })
        return lenta
    })
    .then(function(results) {  //обработка промиса и получение ленты пользователя
        // result should be Media[][]
        var media1 = _.flatten(results.fd);
        var urls1 = _.map(media1, function(medium) {
                //var arr1 = medium.params.images[0].url;
            var arr1 = []

            try {
                arr1 = medium.params.images[0].url
            } catch (err) {
                //console.log("lala")
            }

            return arr1;
            //console.log(medium.params.carouselMedia.images[0].url)
        })

        //console.log(urls1)

        return {id : results.id, linksNoCarousel : urls1, med : media1}
    })
    .then(function(res){

        var urls2 = _.map(res.med, function(medium) {

            var arr2 = []

            try {
                arr2 = medium.params.images[0][0].url
                //console.log(arr2)
            } catch (err) {

            }
            return arr2        
        })

        for (var i = 0; i < 5; i++) {
            if (typeof res.linksNoCarousel[i] == "undefined")
                res.linksNoCarousel[i] = urls2[i];
        }

        var arr3 = []

        for (var i = 0; i < 5; i++) {
            arr3[i] = res.linksNoCarousel[i]
        }

        return {id : res.id, links : arr3}

    })
    .then(function(mediaAndId) {
    	acc.getById(session, mediaAndId.id)
    		.then(function(account) {
    			//console.log(account.params)
    			let avatar = account.params.profilePicUrl;
                let username =  account.params.username;
    			let fullName = account.params.fullName;
    			let bio = account.params.biography;
    			let media0 = mediaAndId.links[0];
    			let media1 = mediaAndId.links[1];
    			let media2 = mediaAndId.links[2];
    			let media3 = mediaAndId.links[3];
    			let media4 = mediaAndId.links[4];

                console.log(avatar)
    			/*console.log(fullName);
    			console.log(bio);
    			console.log(media0);
    			console.log(media1);
    			console.log(media2);
    			console.log(media3);
    			console.log(media4);*/   

    		})
    })
}


Функции парсинга тут асинхронны и так далее, а вот с циклами и асинхронностью я не уверен что у меня все верно. Стоит ли оставить так или как-то переделать можно?
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как реализовать динамичное добавление тегов modelfak23 jQuery 1 19.06.2015 14:27
Как правильно реализовать такой функционал? Julian Общие вопросы Javascript 3 16.01.2015 12:34
Как вы пишете на сервере (node.js) dmitry111 Оффтопик 31 17.05.2014 03:47
Как правильно реализовать наследование? Universe Общие вопросы Javascript 9 10.04.2014 16:05
Как реализовать? Fliand Элементы интерфейса 4 22.08.2009 19:47