- Поисковые системы
- Практика оптимизации
- Трафик для сайтов
- Монетизация сайтов
- Сайтостроение
- Социальный Маркетинг
- Общение профессионалов
- Биржа и продажа
- Финансовые объявления
- Работа на постоянной основе
- Сайты - покупка, продажа
- Соцсети: страницы, группы, приложения
- Сайты без доменов
- Трафик, тизерная и баннерная реклама
- Продажа, оценка, регистрация доменов
- Ссылки - обмен, покупка, продажа
- Программы и скрипты
- Размещение статей
- Инфопродукты
- Прочие цифровые товары
- Работа и услуги для вебмастера
- Оптимизация, продвижение и аудит
- Ведение рекламных кампаний
- Услуги в области SMM
- Программирование
- Администрирование серверов и сайтов
- Прокси, ВПН, анонимайзеры, IP
- Платное обучение, вебинары
- Регистрация в каталогах
- Копирайтинг, переводы
- Дизайн
- Usability: консультации и аудит
- Изготовление сайтов
- Наполнение сайтов
- Прочие услуги
- Не про работу
Что делать, если ваша email-рассылка попала в спам
10 распространенных причин и решений
Екатерина Ткаченко
#Step8 #express REST API
Изначально идея заменить REST обработкой async/awayt без запросов к API несколько усложняла код, в целом это ни к чему, приост проивзодителньости... впринцие он врядли будет от такого решения. Потому:
Express -- сервер на основе которого делают сайты и создают API для REST
body-parser -- парсер HTTP заголовков
можно ещё добавить GrapQL и jsonp / или добвить слой крипто но пока без них, хотя защитить API будет необходимо.
Отправляем - видим:
{"first_name":"john","last_name":"doe"}Таким примерно образом будут реализованы запросы на получение контента, графики, на форматирование (возможно здесь придётся сделать вставку БД) и на загрузку контента в БД сайта и на сами действия и визуализации интерфейса, скрее всего разделять эти действия по отдельным API не будет иметь смысла для проекта такого масштаба.
#Step 9 #content api
Конструируем API под получение и генерацию текста
{"searchengine":"google","content_type":"text","search_request":"node express examples","library":"axios","content_enable_h1_tag":"0"}Для отладки до создания интерфейса под POST - реализация GET -запросом.
#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)
})
...
Собственно REST API сервер под текст готов, примерно так выглядит ответ сервера на запрос по ключу
Так же отдельный микросервисы на изображения, на наполнение базы данных, загрузку на сервер. Примерно такие детали сейчас внутри разных современных модных сервисов, единственное чего нет токена и graphql-ля, но их дальше можно добавить, еще мб будет redis на раздачу заданий и выдачу ключевых фраз..
Наверх ещё rebbitmq для менеджмента таких задач, а парсер контент вынести в задачу. И будет бомба.
Node.SheduleAPI + redis
а за время на изучение рэббита выучить Cassandra
хотя ты мне подкинул задач . теперь ещё rebbitmq протестировать
Cassandra старая и мудренная, тогда лучше уж redis.
Из последних бэнчмарков: это приведенный выше код для получеения контета при доработке и получении из него компанованного контента обогнал собранный аналог на PHP в... дело в том что я в данный момент не могу объктивно полностью оценть возможности предложенного решения поскольку тесты проводятся на локальном канале с "упором" в пропускную способность, что наблюдается на мониторе трафика, но... даже в этих условиях я обогнал PHP -вариант в 32 раза по скорости, то есть у NodeJs -варианта у меня страница с контентом отдаётся через 1.2 секунды после запроса, а у PHP -варианта за 32-40 секунд. Понимаю важны пруфы, но оформление бенчмарка как-нибудь отдельным матералом. Думаю если в любом направлении превосходить основную массу по скорости в 30-40 раз... это качественно другой уровень. Мне лично очень не нравятся колбэки и городить из них небоскрёбы, когда в ООП можно раскидать по классам и вызовам, но.. отчасти это моё нубовство в Node отчасти это просто непривычно... в целом результат мне нравится. Отдельным моментом планирую перевести работу с контентом в Go / C++ ноды, это ускорит работу софта ещё в разы. Пока такой итог, скоро мб выложу новый материал по достройке софта)
Берете reactphp или swoole и работаете в привычной среде, правда небоскребы не исчезнут. А по скорости выйдете на тот же уровень. Правда с блокировками чуть сложнее в такой схеме.
А по скорости выйдете на тот же уровень.
По этому пункту серьезные сомнения, PHP даже с сокетами никогда по производительности не приблизится к NodeJs использующему V8(C++). Вобщем, вопрос касательно PHP и производительности на хайлоаде снят, причём снят давно и не мной. Что касается React/PHP чтобы сказать предметно именно по данному решению нужно проводить тесты.
Берете reactphp или swoole и работаете в привычной среде, правда небоскребы не исчезнут.
Среда как раз непривычная, бибилотека интересная, опять же вопрос времени и накладных расходов на освоение. Вобщем мне не очень хочется разводить здесь Cassandra/Node c PHP/redis стэковые батлы, но скажу что сферы применения той же кассандры и редиса разные, это решения разных классов и сегментов, то же самое можно сказать по reactPHP и Node/ES7async/await / Предлагаю не тратить время, будет свободное, возможно проведу бэнчмарки, тогда можно будет предметно без кофейной гущи делать выводы по вопросу производительности.