#Step 6
Получаем данные с полученных страниц. Думаю в примере не лучшая архитектура и на этапе асинхронных запросов лучше отгужать данные в Redis а оттуда получать очередь асинхронно и уже раскидывать по дальнейшим действиям. Собственно на этом момнте можно добавить сэйв в текст или вставку в базу данных.
const axios = require('axios') const Nightmare = require('nightmare') const cheerio = require('cheerio') const fs = require('fs') const nightmare = Nightmare({ show: true, gotoTimeout: 30 * 1000, // in ms waitTimeout: 30 * 1000 // in ms }); /** * Google serp */ let gsepUrl = 'https://google.com'; let search = 'node books' let opt = { url: gsepUrl, src: search } console.log(opt.url) function getPageGoogleSerp(opt) { r = opt.url + '/search?q=' + opt.src axios.get(r) .then(responce => { d = gserpParseCheerio(responce.data) //walkSites() goAsync(d) d.map((row, elem) => { fs.appendFile('links.txt', JSON.stringify(row) + "\r\n", (err) => { if (err) throw err; //console.log('Saved!'); }); //console.log(JSON.stringify(row)); //console.log(elem); }) }) .catch(err => { console.log(err); }) } let gserpParseCheerio = html => { data = []; const $ = cheerio.load(html); $(html).find('div.ZINbbc.xpd.O9g5cc.uUPGi div.kCrYT').each((row, raw_element) => { let link = $(raw_element).find('a').attr('href'); let title = $(raw_element).find('a').text(); if (link) { let a = link.split("?q=")[1].split("&sa=")[0]; console.log(JSON.stringify({ title : title, link : a })); data.push({ title : title, link : a }); } }); return data; } let fwriteLink = links => { } let walkSites = links => { links.map((row, elem) => { console.log(row.link) axios.get(row.link) .then(responce => { console.log(responce) }) .catch(err => { console.log(err); }) }) } //add async async function goAsync(urls) { let netPromises = urls.map(walkSitesAsyncAxios); d = await Promise.all(netPromises); console.log(d) return d; } let walkSitesAsyncAxios = links => { return axios.get(links.link) .then(responce => { //if (responce.status) { if (responce.status && responce.status == 200 && responce.statusText == 'OK' && responce.request.res.responseUrl == links.link) { pageData = []; const $ = cheerio.load(responce.data); let title = $('title').text(); let description = $('meta[name=description]').attr('content'); let p = $(responce.data).find('p').text(); p = '<p>' + p.replace(/\n{2,}/g, "</p><p>").replace(/\n/g, "<br>") + '</p>'; //console.log('Title: ' + title) //console.log('Description: ' + description) //console.log('P: ' + p) pageData.push({ link : links.link, title : title, description : description, text : p }); //console.log(JSON.stringify(pageData)) //console.log(pageData) return { link : links.link, title : title, description : description, text : p, success: true }; //console.log(responce.data) //console.log(responce.request.path) //console.log(responce.request.res.responseUrl) //console.log(responce.request.res.isAxiosError) } else return { success: false }; //} else return { success: false }; }) .catch(err => { // Error if (err.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx // console.log(error.response.data); // console.log(error.response.status); // console.log(error.response.headers); } else if (err.request) { // The request was made but no response was received // 'error.request' is an instance of XMLHttpRequest in the // browser and an instance of // http.ClientRequest in node.js //console.log(err.request); } else { // Something happened in setting up the request that triggered an Error //console.log(err.config); //console.log('Error', err.message); } //console.log(err); return { success: false }; }) } getPageGoogleSerp(opt)
npm start
Twickbot, давай ты воздержишся впредь от подобных реплк в мой адрес. Также не совсем корректно постить сюда пиарлинки, но ок, ты это протащил через "3 строчки" кода, обсуждать мой уровень компетенции это также офтоп, во-первых я его здесь не демонстрирую в полной мере и не намерен, во-вторых - это примеры для начинающих, то есть не ставится задача создать нечто сложное, но и потом здесь рассмотрена работа именно с Nodejs, мне конечно интерсно что можно делать таким ботом затрачивая лишний ресурс на эмуляцю окна браузера чего нельзя обойти с использованием меньших ресурсов, не качая разный непонятный софт, который похоже основан на том же селениуме.. То есть в целом ты мог разместить здесь своё решение, и это бы не было вроде как офтопом, но отпускать подобные реплики, навешивать какие-то ярлыки, придираться к уровню мануалов... ты просто ведешь себя некорректно и вызывающе, это не добавляет плюсов ни тебе ни твоим продуктам. Я бы на твоём месте поработал над корректностью самопрезентации и так не позорился больше, хотя это уже не в первый раз с твоей стороны, и я почему-то думаю что ты над собой не работаешь в данном направлении, и в ответ я услышу какую-то бессвязную брань в свой адрес, подобную той что ты написал выше, на чем диалог с тобой прекращаю.---------- Добавлено 12.10.2019 в 11:03 ----------
Ну и в дополнение чтобы окончательно уже вбитьгвоздьвнеускушеннуюголову прояснть момент по SeleniumServer и оконной эмуляуции браузер в "натуральном виде", то.. приводил пример и объяснял что для обхода защит сервисов, снимающих события мыши для использовани в сценариях на странице не обязательно эти события отправлять, достаточно их обойти и это не сложнее чем выполнить в эмуляции браузера (технически по объёму действий при разработке), записывать шаги как в других софтах или набирать сценарии на внутреннем языке сценариев софта.. и это производительнее (!!!) эффективнее NodeJs сейчас ничего нет для этих задач ни в отношении скорости написания, не по числу поддерживаемых платформ ни по производительности. Этот вопос изучался достаточно долго. Всё, вопрос закрыт, несогласные могу дальше писать под Selenium - ваше право.---------- Добавлено 12.10.2019 в 11:28 ----------#Step 5
Теперь несколько увеличим скорость работы бота добавив асинхронность. Асинхронность в JavaScript нескольrо похожа на одношаговую многопоточность без управления ресурсами потоков и с использованием разделяемой памяти, но для пакетного получения ответа по списку ссылок этого вполне достатчно, что собственно и происходит в браузере при подгрузке все скриптов - они прогружаются асинхронно, что позволяет ускорить получение собранного кода сраницы.
const axios = require('axios')const Nightmare = require('nightmare')const cheerio = require('cheerio')const fs = require('fs')const nightmare = Nightmare({ show: true, gotoTimeout: 30 * 1000, // in ms waitTimeout: 30 * 1000 // in ms});/** * Google serp */let gsepUrl = 'https://google.com';let search = 'node books'let opt = { url: gsepUrl, src: search}console.log(opt.url)function getPageGoogleSerp(opt) { r = opt.url + '/search?q=' + opt.src axios.get(r) .then(responce => { d = gserpParseCheerio(responce.data) //walkSites() goAsync(d) d.map((row, elem) => { fs.appendFile('links.txt', JSON.stringify(row) + "\r\n", (err) => { if (err) throw err; //console.log('Saved!'); }); //console.log(JSON.stringify(row)); //console.log(elem); }) }) .catch(err => { console.log(err); })}let gserpParseCheerio = html => { data = []; const $ = cheerio.load(html); $(html).find('div.ZINbbc.xpd.O9g5cc.uUPGi div.kCrYT').each((row, raw_element) => { let link = $(raw_element).find('a').attr('href'); let title = $(raw_element).find('a').text(); if (link) { let a = link.split("?q=")[1].split("&sa=")[0]; console.log(JSON.stringify({ title : title, link : a })); data.push({ title : title, link : a }); } }); return data;}let fwriteLink = links => { }let walkSites = links => { links.map((row, elem) => { console.log(row.link) axios.get(row.link) .then(responce => { console.log(responce) }) .catch(err => { console.log(err); }) })}//add asyncasync function goAsync(urls) { let netPromises = urls.map(walkSitesAsyncAxios); return await Promise.all(netPromises);}let walkSitesAsyncAxios = links => { axios.get(links.link) .then(responce => { console.log(responce) }) .catch(err => { console.log(err); })}getPageGoogleSerp(opt)
XPraptor, ещё и буквоед)) мне хоть новое пришествие, молодец вобщем... ты понял))---------- Добавлено 11.10.2019 в 22:19 ----------#Step 4
Теперь научим бота гулять по полученному списку линков и сохранять результат в файл:
const axios = require('axios') const Nightmare = require('nightmare') const cheerio = require('cheerio') const fs = require('fs') const nightmare = Nightmare({ show: true, gotoTimeout: 30 * 1000, // in ms waitTimeout: 30 * 1000 // in ms }); /** * Google serp */ let gsepUrl = 'https://google.com'; let search = 'node books' let opt = { url: gsepUrl, src: search } console.log(opt.url) function getPageGoogleSerp(opt) { r = opt.url + '/search?q=' + opt.src axios.get(r) .then(responce => { d = gserpParseCheerio(responce.data) walkSites(d) d.map((row, elem) => { fs.appendFile('links.txt', JSON.stringify(row) + "\r\n", (err) => { if (err) throw err; //console.log('Saved!'); }); //console.log(JSON.stringify(row)); //console.log(elem); }) }) .catch(err => { console.log(err); }) } let gserpParseCheerio = html => { data = []; const $ = cheerio.load(html); $(html).find('div.ZINbbc.xpd.O9g5cc.uUPGi div.kCrYT').each((row, raw_element) => { let link = $(raw_element).find('a').attr('href'); let title = $(raw_element).find('a').text(); if (link) { let a = link.split("?q=")[1].split("&sa=")[0]; console.log(JSON.stringify({ title : title, link : a })); data.push({ title : title, link : a }); } }); return data; } let fwriteLink = links => { } let walkSites = links => { links.map((row, elem) => { console.log(row.link) axios.get(row.link) .then(responce => { console.log(responce) }) .catch(err => { console.log(err); }) }) } getPageGoogleSerp(opt)
Честно бро. поднадоел ты да ты уж прости за резкость---------- Добавлено 11.10.2019 в 20:21 ----------#Step 3
Забираем ссылки со страницы. Учитывая что у гугла разная верстка при запросах с разнгых юзерагентов это также необходимо учесть, нармер задампив возвращаемую страницу выдачи в файл и оттуда получив необходимые селекторы.
const axios = require('axios')const Nightmare = require('nightmare')const cheerio = require('cheerio')const fs = require('fs')const nightmare = Nightmare({ show: true, gotoTimeout: 30 * 1000, // in ms waitTimeout: 30 * 1000 // in ms});/** * Google serp */let gsepUrl = 'https://google.com';let search = 'node books'let opt = { url: gsepUrl, src: search}console.log(opt.url)function getPageGoogleSerp(opt) { r = opt.url + '/search?q=' + opt.src axios.get(r) .then(responce => { console.log(gserpParseCheerio(responce.data)); }) .catch(e => { console.log(e); })}let gserpParseCheerio = html => { data = []; const $ = cheerio.load(html); $(html).find('div.ZINbbc.xpd.O9g5cc.uUPGi div.kCrYT').each((row, raw_element) => { let link = $(raw_element).find('a').attr('href'); let title = $(raw_element).find('a').text(); if (link) { //console.log(link) //console.log(title) data.push({ title : title, link : link }); } }); return data;}getPageGoogleSerp(opt)
npm install fsnpm start
... { title: 'Practical Node.js by Azat ...Node.js Design Pattern ...Mastering Node.js', link: '/url?q=https://codeforgeek.com/top-5-node-js-books-read/%23practical-node.js-by-azat-mardan&sa=U&ved=2ahUKEwjbgqi925TlAhWIecAKHSe_C9cQ0gIwBHoECAcQAg&usg=AOvVaw15Cc5hG2Q_TYm6r4YKqkNi' }, { title: '11 Best New Node.js Books To Read In 2019 - BookAuthorityhttps://bookauthority.org › ... › Software Development › Node.js Books', link: '/url?q=https://bookauthority.org/books/new-nodejs-books&sa=U&ved=2ahUKEwjbgqi925TlAhWIecAKHSe_C9cQFjAFegQICBAB&usg=AOvVaw1RitRjpDMtqO4k_0rgZ4zj' }, { title: 'The best books to learn node? : node - Reddithttps://www.reddit.com › node › comments › the_best_books_to_learn_node', link: '/url?q=https://www.reddit.com/r/node/comments/97cazs/the_best_books_to_learn_node/&sa=U&ved=2ahUKEwjbgqi925TlAhWIecAKHSe_C9cQFjAGegQIARAB&usg=AOvVaw3wLU9ahOm9TfViBPDraccU' }, { title: 'Learn Nodejs: Best Nodejs courses, tutorials & books 2019 ...https://reactdom.com › node', link: '/url?q=https://reactdom.com/node&sa=U&ved=2ahUKEwjbgqi925TlAhWIecAKHSe_C9cQFjAHegQIAhAB&usg=AOvVaw3I62V62JdZ9pHhqHQOVYzr' }, { title: 'Node.js Books to Read and Master the Technology | Railsware Bloghttps://railsware.com › blog › best-node-js-books-to-master-the-technology', link: '/url?q=https://railsware.com/blog/best-node-js-books-to-master-the-technology/&sa=U&ved=2ahUKEwjbgqi925TlAhWIecAKHSe_C9cQFjAIegQIBRAB&usg=AOvVaw24XmDphoNgYtYeRwKAG1yx' }, { title: 'Express books and blogs - Express.jshttps://expressjs.com › resources › books-blogs', link: '/url?q=https://expressjs.com/es/resources/books-blogs.html&sa=U&ved=2ahUKEwjbgqi925TlAhWIecAKHSe_C9cQFjAJegQIAxAB&usg=AOvVaw0E-yWYgDsWwWa6jqwfGzzQ' }
XPraptor, тебе ничего не собираюсь доказывать, а код выкладывал)) и даже скрин коотрый было тяжело не заметить))
XPraptor, хватит заниматься искажением фактов, твой пример я прошел, то что я переловил события и напрямую отправил уже вопрос техники. Вобщем давай.. молодец.. удачи итд))
слушай, если ты такойграмотный, создай соседний похожий топик и там испускай лучи интелекта))
юни, суть вопроса, точнее практика - выше, а софистику я не люблю и таких людей которые рассуждают безпредметно, бездоказательно, тем более в негативном ключе о ком-либо также не особо... как бы сказть.. ну думаю понял))
3. Следующим шагом -- прокидываем поисковый запрос массивом в функцию запроса, собс в массиве могут появиться прокси и другие параметры запроса.
const axios = require('axios')const Nightmare = require('nightmare')const cheerio = require('cheerio')const nightmare = Nightmare({ show: true, gotoTimeout: 30 * 1000, // in ms waitTimeout: 30 * 1000 // in ms});/** * Google serp */let gsepUrl = 'https://google.com';let search = 'node books'let opt = { url: gsepUrl, src: search}console.log(opt.url)function getPageGoogleSerp(opt) { r = opt.url + '/search?q=' + opt.search axios.get(r) .then(responce => { //console.log(responce); gserpParseCheerio(responce.data) }) .catch(e => { console.log(e); })}let gserpParseCheerio = html => { data = []; const $ = cheerio.load(html); console.log(html);}getPageGoogleSerp(opt)//Google serp
запускаем
видим код выдачи по запросу
хостинг это круто. я очень рад за тебя. искренне---------- Добавлено 11.10.2019 в 14:55 ----------Собственно начнём следующий урок -- это парсинг google
const axios = require('axios')const Nightmare = require('nightmare')const cheerio = require('cheerio')const nightmare = Nightmare({ show: true, gotoTimeout: 30 * 1000, // in ms waitTimeout: 30 * 1000 // in ms});/** * Google serp */const gsepUrl = 'https://google.com';function getPageGoogleSerp(url) { axios.get(url) .then(responce => { console.log(responce); }) .catch(e => { console.log(e); })}getPageGoogleSerp(gsepUrl)
1. ставим ноду
2. прописываем в пакедж скрипт запуска
3. запускаем с консоли
4. видим
5. переходим к след шагу---------- Добавлено 11.10.2019 в 15:02 ----------Stage #2
Подключаем DOM-парсер, библиотека Cheerio
const axios = require('axios')const Nightmare = require('nightmare')const cheerio = require('cheerio')const nightmare = Nightmare({ show: true, gotoTimeout: 30 * 1000, // in ms waitTimeout: 30 * 1000 // in ms});/** * Google serp */const gsepUrl = 'https://google.com';function getPageGoogleSerp(url) { axios.get(url) .then(responce => { //console.log(responce); gserpParseCheerio(responce.data) }) .catch(e => { console.log(e); })}let gserpParseCheerio = html => { data = []; const $ = cheerio.load(html); console.log(html);}
Запускаем
Видим HTML -код старницы выдачи (пока без запроса).
Остаётся порадоваться что защиту гугла и фейспука писали не такие отодоксальные мученики низкоуровневого проограммирования как ты, сидящие в кельях над несколькими модулями, и вобщем на этой ноте идти ботить их потому что там деньги а в разговоре денег нет.. ---------- Добавлено 11.10.2019 в 13:34 ----------
ты понимешь... какбы тебе сказать. ему пофиг вообще. сколько там памяти какая там скорость.. его интересует приход в час... на счёт в долларах. если тебе про память и скорость -- пожалуйста, но мне на другую сторону улицы)) ты уш прости.