Бототворения псто

billypelegrini
На сайте с 20.02.2019
Offline
47
#151

#Step8 #express REST API

Изначально идея заменить REST обработкой async/awayt без запросов к API несколько усложняла код, в целом это ни к чему, приост проивзодителньости... впринцие он врядли будет от такого решения. Потому:

npm i express body-parser

Express -- сервер на основе которого делают сайты и создают API для REST

body-parser -- парсер HTTP заголовков

можно ещё добавить GrapQL и jsonp / или добвить слой крипто но пока без них, хотя защитить API будет необходимо.


//app.js
var express = require('express');
var app = express();

// HTTP header parser
var bodyParser = require('body-parser');

// Create parser for HTTP POST application/x-www-form-urlencoded
var urlencodedParser = bodyParser.urlencoded({extended: false})

// Router GET
app.get('/process_get', function (req, res) {
// Подготовка вывода в формате JSON
response = {
first_name: req.query.first_name,
last_name: req.query.last_name
};
console.log(response);
res.end(JSON.stringify(response));
})

// Router POST


var server = app.listen(3000, function () {

var host = server.address().address
var port = server.address().port

console.log("Content Server listening at http://%s:%s", host, port)
})

node app.js

http://localhost:3000/process_get?first_name=john&last_name=doe

Отправляем - видим:

{"first_name":"john","last_name":"doe"}

Таким примерно образом будут реализованы запросы на получение контента, графики, на форматирование (возможно здесь придётся сделать вставку БД) и на загрузку контента в БД сайта и на сами действия и визуализации интерфейса, скрее всего разделять эти действия по отдельным API не будет иметь смысла для проекта такого масштаба.

billypelegrini
На сайте с 20.02.2019
Offline
47
#152

#Step 9 #content api

Конструируем API под получение и генерацию текста


app.get('/parser_api_get', function (req, res) {
// Prepare output formated in JSON
response = {

searchengine : req.query.searchengine, //google
content_type : req.query.content_type, //text
search_request : req.query.search_request, //keyword
library : req.query.library, //axios
useragent : req.query.useragent, //chrome
proxy_server : req.query.proxy_server, //chrome

/** H1 in articles */
content_enable_h1_tag : req.query.content_enable_h1_tag, // boolean/blob 1 | 0

/** percent of paraphs prev begin by H1 tag 0-100(%) -- insert AFRER paragraph*/
content_h1_tag_freq_percent : req.query.content_h1_tag_freq_percent, // 0-100(%)

/** source for create H1 text */
content_h1_tag_source : req.query.content_h1_tag_source, // one.random.keyword.from.keywords / extracted.h1.from.parsed.sites.by.selected.keyword


/** H2 in articles */
content_enable_h2_tag : req.query.content_enable_h2_tag, // boolean/blob 1 | 0

/** percent of paraphs prev begin by H1 tag 0-100(%) -- insert AFRER paragraph*/
content_h2_tag_freq_percent : req.query.content_h2_tag_freq_percent, // 0-100(%)

/** source for create H2 text */
content_h2_tag_source : req.query.content_h2_tag_source, // one.random.keyword.from.keywords / extracted.h2.from.parsed.sites.by.selected.keyword


/** H3 in articles */
content_enable_h3_tag : req.query.content_enable_h3_tag, // boolean/blob 1 | 0

/** percent of paraphs prev begin by H3 tag 0-100(%) -- insert AFRER paragraph*/
content_h3_tag_freq_percent : req.query.content_h3_tag_freq_percent, // 0-100(%)

/** source for create H3 text */
content_h3_tag_source : req.query.content_h3_tag_source, // one.random.keyword.from.keywords / extracted.h3.from.parsed.sites.by.selected.keyword


/** IMG in articles -- insert BEFORE paragraph*/
content_enable_img_tag : req.query.content_enable_img_tag, // boolean/blob 1 | 0

/** percent of paraphs prev begin by IMG tag 0-100(%) -- insert BEFORE paragraph*/
content_img_tag_freq_percent : req.query.content_img_tag_freq_percent, // 0-100(%)

/** source for create IMG in text */
content_img_source : req.query.content_img_source, // google.image.advanced.search / flickr / pinterest

/** license type for IMG in text */
content_img_license_type : req.query.content_img_license_type, // cc / all

/** width type for IMG in text */
content_img_width : req.query.content_img_width // 400 / 600 / 800 / 1000 /any
};
console.log(response);
res.end(JSON.stringify(response));
})
// localhost:3000/parser_api_get?searchengine=google&content_type=text&search_request=node+express+examples&library=axios&content_enable_h1_tag=0

node app.js

Content Server listening at http://:::3000

http://localhost:3000/parser_api_get?searchengine=google&content_type=text&search_request=node+express+examples&library=axios&content_enable_h1_tag=0

{"searchengine":"google","content_type":"text","search_request":"node express examples","library":"axios","content_enable_h1_tag":"0"}

Для отладки до создания интерфейса под POST - реализация GET -запросом.

billypelegrini
На сайте с 20.02.2019
Offline
47
#153

#Step 10 #add content api selector

Добавляем селектор, подключаем модули:

var express = require('express');

var app = express();

// HTTP header parser
var bodyParser = require('body-parser');

// Create parser for HTTP POST application/x-www-form-urlencoded
var urlencodedParser = bodyParser.urlencoded({extended: false})


//DEBUG / NOTIFY
var debugLevel = 5

// Router GET
app.get('/process_get', function (req, res) {
// Prepare output formated in JSON
response = {
first_name: req.query.first_name,
last_name: req.query.last_name
};
console.log(response);
res.end(JSON.stringify(response));
})

//searchengine : google
//contenttype : text
//searchrequest : keyword
//useragent : chrome
//library : axios

app.get('/parser_api_get', function (req, res) {
// Prepare output formated in JSON
response = {

searchengine : req.query.searchengine, //google
content_type : req.query.content_type, //text / image
search_request : req.query.search_request, //keyword
library : req.query.library, //axios
useragent : req.query.useragent, //chrome
proxy_server : req.query.proxy_server, //chrome

/** H1 in articles */
content_enable_h1_tag : req.query.content_enable_h1_tag, // boolean/blob 1 | 0

/** percent of paraphs prev begin by H1 tag 0-100(%) -- insert AFRER paragraph*/
content_h1_tag_freq_percent : req.query.content_h1_tag_freq_percent, // 0-100(%)

/** source for create H1 text */
content_h1_tag_source : req.query.content_h1_tag_source, // one.random.keyword.from.keywords / extracted.h1.from.parsed.sites.by.selected.keyword


/** H2 in articles */
content_enable_h2_tag : req.query.content_enable_h2_tag, // boolean/blob 1 | 0

/** percent of paraphs prev begin by H1 tag 0-100(%) -- insert AFRER paragraph*/
content_h2_tag_freq_percent : req.query.content_h2_tag_freq_percent, // 0-100(%)

/** source for create H2 text */
content_h2_tag_source : req.query.content_h2_tag_source, // one.random.keyword.from.keywords / extracted.h2.from.parsed.sites.by.selected.keyword


/** H3 in articles */
content_enable_h3_tag : req.query.content_enable_h3_tag, // boolean/blob 1 | 0

/** percent of paraphs prev begin by H3 tag 0-100(%) -- insert AFRER paragraph*/
content_h3_tag_freq_percent : req.query.content_h3_tag_freq_percent, // 0-100(%)

/** source for create H3 text */
content_h3_tag_source : req.query.content_h3_tag_source, // one.random.keyword.from.keywords / extracted.h3.from.parsed.sites.by.selected.keyword


/** IMG in articles -- insert BEFORE paragraph*/
content_enable_img_tag : req.query.content_enable_img_tag, // boolean/blob 1 | 0

/** percent of paraphs prev begin by IMG tag 0-100(%) -- insert BEFORE paragraph*/
content_img_tag_freq_percent : req.query.content_img_tag_freq_percent, // 0-100(%)

/** source for create IMG in text */
content_img_source : req.query.content_img_source, // google.image.advanced.search / flickr / pinterest

/** license type for IMG in text */
content_img_license_type : req.query.content_img_license_type, // cc / all

/** width type for IMG in text */
content_img_width : req.query.content_img_width // 400 / 600 / 800 / 1000 /any
};

//TO EXPORT
//MAIN CONTENT API SWITCHER
switch (response.searchengine) {
case 'google' :
if (debugLevel >= 1) console.log('go.google')

//to export
//CONTENT TYPE SWITCHER
switch (response.content_type) {
case 'text' :
if (debugLevel >= 1) console.log('Content type is text')

//to export
//REQUEST OPTS
if (response.search_request) {
if (debugLevel >= 2) console.log('Search : ' + response.search_request)

let search = response.search_request
let crawlerLybrary
if (response.library && (response.library == 'axios' || response.library == 'nightmare' ) ) {
crawlerLybrary = response.library
} else {
crawlerLybrary = 'axios'
}
if (debugLevel >= 2) console.log('Crawl with lybrary : ' + crawlerLybrary)
if (debugLevel >= 2) console.log('Search : ' + search)

//to export
//CRAWLER OPTS

let useragent = ''
let proxy_server = []

if (response.useragent) {
useragent = response.useragent
}

if (response.proxy_server) {
//add proxy_server.push || parse.str && push.elem
proxy_server = response.proxy_server
}

if (debugLevel >= 3) console.log('Useragent : ' + useragent)
if (debugLevel >= 3) console.log('Proxy server : ' + proxy_server)
//useragent
//proxy_server
//end CRAWLER OPTS

//REQUEST OPTS PIPE / MUX
let requestOptions = []

requestOptions = {
searchengine : 'google.com',
search_request : search,
useragent : useragent,
proxy_server : proxy_server
}
if (debugLevel >= 1) console.log(requestOptions)
//end REQUEST OPTS PIPE / MUX

//MODULE SELECT
switch (crawlerLybrary) {
case 'axios' :

const getPageGoogleSerp = require('../../se/getPageGoogleSerp')

if (debugLevel >= 1) console.log('Get article with axios.module. With options :')
if (debugLevel >= 1) console.log(requestOptions)

getPageGoogleSerp(requestOptions)

break
case 'nightmare' :



break
}
//end MODULE SELECT

} else {
if (debugLevel >= 1) console.log('Search request not set. Action ended.')
}
//end REQUEST OPTS

break
case 'image' :
if (debugLevel >= 1) console.log('Content type is image')
break
default :
if (debugLevel >= 1) console.log('Content type not set')
break
}
//END CONTENT TYPE SWITCHER --> module.export / const contentTypeSwitcher = require(./contentTypeSwitcher)

break
case 'bing' :
if (debugLevel >= 1) console.log('go.bing')
//export
//CONTENT TYPE SWITCHER

break
case 'yahoo' :
if (debugLevel >= 1) console.log('go.yahoo')
//export
//CONTENT TYPE SWITCHER

break
case 'any' :
if (debugLevel >= 1) console.log('go: google & bing & yahoo')
//export
//CONTENT TYPE SWITCHER

break
}

console.log(response.searchengine);

//console.log(response);
res.end(JSON.stringify(response));
})
// localhost:3000/parser_api_get?searchengine=google&content_type=text&search_request=node+express+examples&library=axios&content_enable_h1_tag=0



// Router POST


var server = app.listen(3000, function () {

var host = server.address().address
var port = server.address().port

console.log("Content Server listening at http://%s:%s", host, port)
})

node app.js

http://localhost:3000/parser_api_get?searchengine=google&content_type=text&search_request=node+express+examples&library=axios&content_enable_h1_tag=0

...

billypelegrini
На сайте с 20.02.2019
Offline
47
#154

Собственно REST API сервер под текст готов, примерно так выглядит ответ сервера на запрос по ключу

Так же отдельный микросервисы на изображения, на наполнение базы данных, загрузку на сервер. Примерно такие детали сейчас внутри разных современных модных сервисов, единственное чего нет токена и graphql-ля, но их дальше можно добавить, еще мб будет redis на раздачу заданий и выдачу ключевых фраз..

bolyk
На сайте с 16.02.2006
Offline
175
#155

Наверх ещё rebbitmq для менеджмента таких задач, а парсер контент вынести в задачу. И будет бомба.

Thunder v3. Дорген (http://ifirestarter.ru/product/10) | MassSiteProxy. Скрипт клонирования сайтов (http://ifirestarter.ru/product/12) | CPAgen CPA дорген (http://ifirestarter.ru/product/14) | (http://fast-index.ru/article)
billypelegrini
На сайте с 20.02.2019
Offline
47
#156

Node.SheduleAPI + redis

а за время на изучение рэббита выучить Cassandra

хотя ты мне подкинул задач . теперь ещё rebbitmq протестировать

bolyk
На сайте с 16.02.2006
Offline
175
#157

Cassandra старая и мудренная, тогда лучше уж redis.

billypelegrini
На сайте с 20.02.2019
Offline
47
#158

Из последних бэнчмарков: это приведенный выше код для получеения контета при доработке и получении из него компанованного контента обогнал собранный аналог на PHP в... дело в том что я в данный момент не могу объктивно полностью оценть возможности предложенного решения поскольку тесты проводятся на локальном канале с "упором" в пропускную способность, что наблюдается на мониторе трафика, но... даже в этих условиях я обогнал PHP -вариант в 32 раза по скорости, то есть у NodeJs -варианта у меня страница с контентом отдаётся через 1.2 секунды после запроса, а у PHP -варианта за 32-40 секунд. Понимаю важны пруфы, но оформление бенчмарка как-нибудь отдельным матералом. Думаю если в любом направлении превосходить основную массу по скорости в 30-40 раз... это качественно другой уровень. Мне лично очень не нравятся колбэки и городить из них небоскрёбы, когда в ООП можно раскидать по классам и вызовам, но.. отчасти это моё нубовство в Node отчасти это просто непривычно... в целом результат мне нравится. Отдельным моментом планирую перевести работу с контентом в Go / C++ ноды, это ускорит работу софта ещё в разы. Пока такой итог, скоро мб выложу новый материал по достройке софта)

bolyk
На сайте с 16.02.2006
Offline
175
#159

Берете reactphp или swoole и работаете в привычной среде, правда небоскребы не исчезнут. А по скорости выйдете на тот же уровень. Правда с блокировками чуть сложнее в такой схеме.

billypelegrini
На сайте с 20.02.2019
Offline
47
#160
bolyk:
А по скорости выйдете на тот же уровень.

По этому пункту серьезные сомнения, PHP даже с сокетами никогда по производительности не приблизится к NodeJs использующему V8(C++). Вобщем, вопрос касательно PHP и производительности на хайлоаде снят, причём снят давно и не мной. Что касается React/PHP чтобы сказать предметно именно по данному решению нужно проводить тесты.

bolyk:
Берете reactphp или swoole и работаете в привычной среде, правда небоскребы не исчезнут.

Среда как раз непривычная, бибилотека интересная, опять же вопрос времени и накладных расходов на освоение. Вобщем мне не очень хочется разводить здесь Cassandra/Node c PHP/redis стэковые батлы, но скажу что сферы применения той же кассандры и редиса разные, это решения разных классов и сегментов, то же самое можно сказать по reactPHP и Node/ES7async/await / Предлагаю не тратить время, будет свободное, возможно проведу бэнчмарки, тогда можно будет предметно без кофейной гущи делать выводы по вопросу производительности.

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий