как с помощью phantomjs пройти по ссылкам
Как с помощью phantomjs обойти массив ссылко, от код и не работает???
var webpage=require('webpage'); var url=[]; url[0]="http://google.ru"; url[1]="http://microsoft.com"; var page=webpage.create(); for(var i=0;i<url.length;i++) { console.log(url[i]); page.open(url[i],function(status){ if(status==="success"){ console.log("success"+i); page.render("img"+i+".png"); }else { console.log("not success"+i); } }); } //phantom.exit(); |
Так что никто не знает как делать? Я знаю можно черзе таймер и switch, но мне хочется через цикл по простому сделать. Как сделать так чтобы цикл ожидал завершения работы функции page.open, а затем только шел дальше?????
|
Так что через таймеры делать? Похоже вариантов нету. Или можно как то сделать чтобы функция open не возвращала управление сразу, а только после выполнения????
|
Суть событийного программирования, состоит в построении цепочек из callback функций.
На вскидку: url[0]="http://google.ru"; url[1]="http://microsoft.com"; i = 0; function parse(i) { page.open(url[i], function() { ... ... ... i++ if(url[i]) parse(i); }); } Конечно можно и покрасивее это сделать. |
Цитата:
|
Максимальная глубина рекурсии в браузерах ограничена, точно можно рассчитывать на 10000 вложенных вызовов, но некоторые интерпретаторы допускают и больше.
https://learn.javascript.ru/recursion |
вообе кумарит это phantom, похоже нужно еще и задержку делать после выхода из функции open, если не делать задержку то оно с ошибками парсит или я что то не то делаю хз.
|
Цитата:
|
Вот код написал
var webpage=require('webpage'); var url=[]; url[0]="http://google.ru"; url[1]="http://microsoft.com"; url[2]="http://kselax.ru"; url[3]="http://cyberforum.ru"; url[4]="http://fl.ru"; url[5]="http://podrobnosti.ua"; var page=webpage.create(); //устанавливаем 10 секунд ожидания запроса page.settings.onResourceTimeout=500; var step=1; var time=500; var intervalId=setInterval(tick,time); var i=0; function tick(){ switch(step){ case 1:{ clearInterval(intervalId);//останавливаем счетчик step=2; console.log(url[i]); page.settings.resourceTimeout=15000;//время ожидания 15 секунд page.open(url[i],function(status){ if(status==="success"){ console.log("success"+i); page.render("img"+i+".png"); i++; if(i<url.length) { // clearInterval(intervalId); // intervalId=setInterval(tick,time); step=1; } else step=3; } else{ console.log("not success"+i); i++; if(i<url.length) { // clearInterval(intervalId); // intervalId=setInterval(tick,time); step = 1; } else step=3; } }); intervalId=setInterval(tick,time); break; } case 2:{ console.log("TICK"+step); break; } case 3:{ clearInterval(intervalId); phantom.exit(); } } } Он у меня два раза копирует одни и теже изображения, а когда раскоменнтирую строки переустановки счетчика тогда нормально. Че так? Че он неуспевает обнулятся или че за нафиг? На нем большие парсера можно написать или нет?, Это ужас постоянно таймеры запускать :( Щас и с задержкой половина урлов не спарсило, мб. большую нужно поставить, 500 вроде мало, когда ставил 1000 то норм было. Как он работает не ясно.... Через раз парсит, раз норм все урлы, а другой раз пару урлов. |
от так сделал тоже через раз копирует изображения и бывают одинаковые. хз. че оно так лагает
var webpage=require("webpage"); var page=webpage.create(); var url=[]; url[0]="http://google.ru"; url[1]="http://microsoft.com"; url[2]="http://kselax.ru"; url[3]="http://cyberforum.ru"; url[4]="http://fl.ru"; url[5]="http://podrobnosti.ua"; var i=0; pars(); function pars(){ page.settings.resourceTimeout=10000; page.open(url[i],function(status){ if(status=="success"){ console.log("success"+i) page.render("img"+i+".png"); if(++i<url.length){pars();} else{phantom.exit();} } else{ console.log("not success"+i) if(++i<url.length){pars();} else{phantom.exit();} } }); }; Мб. что то в коде не так, нужно мб. как то phantomjs останавливать или что то делать???? |
Цитата:
|
i=0 tst=function(){i++; try{tst()}catch(e){console.log(i)}} tst() i=0 tst=function(){if(i===30000) return console.log(i); i++; setTimeout(function(){tst()})} tst() /* результат для ноды: 11434 30000 */ скорей всего для асинхронных вызовов нет ограничений. Но они медленней. UPD хотя на хроме этот код не отрабатывает почему-то, вывода в консоль нет. В ФФ -- ок |
хром 40к без Timeout стек переполнен !
function f (i) { console.log(1) if(i > 0) setTimeout(function () {f(i-1)}, 0); else console.log(i) } f(40000) |
а как вообще парсера пишутся на phantomjs???? Мб. просто маленькие скрипты посоздавать которые будут по одному урлу считывать, а затем создавать процесс и вызывать консоль со скриптом???
А если так сделать, то куки пропадут да? Массив из 5 ссылок нормально спарсить не могу даже. |
можно пошаманить и обойти стек :)
function f (i, t) { if(t == 10000) { setTimeout(function () { console.log(i) f(i, 0) }, 0); } else if(i) f(i-1, t+1); } var a = 100000; f(a, 0) |
|
Цитата:
var webpage=require("webpage"); var url=[]; url[0]="http://google.ru"; url[1]="http://microsoft.com"; url[2]="http://kselax.ru"; url[3]="http://cyberforum.ru"; url[4]="http://fl.ru"; url[5]="http://podrobnosti.ua"; var i=0; pars(); function pars(){ var page=webpage.create(); page.settings.resourceTimeout=10000; page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0'; page.open(url[i],function(status){ if(status=="success"){ console.log("success"+i) page.render("img"+i+".png"); page.close(); if(++i<url.length){pars();} else{phantom.exit();} } else{ console.log("not success"+i) page.close(); if(++i<url.length){pars();} else{phantom.exit();} } }); }; А раньше по разному парсило, то 2 страницы, то 3, то урлы разные, а изображения одинаковые, вроде разобрался. Вот с помощью switch типо отлова сообщений var webpage=require('webpage'); var url=[]; url[0]="http://google.ru"; url[1]="http://microsoft.com"; url[2]="http://kselax.ru"; url[3]="http://cyberforum.ru"; url[4]="http://fl.ru"; url[5]="http://podrobnosti.ua"; var step=1; var time=500; var intervalId=setInterval(tick,time); var i=0; function tick(){ switch(step){ case 1:{ clearInterval(intervalId);//останавливаем счетчик step=2; console.log(url[i]); var page=webpage.create(); page.settings.resourceTimeout=15000;//время ожидания 15 секунд page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0'; page.open(url[i],function(status){ if(status==="success"){ console.log("success"+i); page.render("img"+i+".png"); page.close(); i++; if(i<url.length) {step=1;} else step=3; } else{ page.close(); console.log("not success"+i); i++; if(i<url.length) {step = 1;} else step=3; } }); intervalId=setInterval(tick,time); break; } case 2:{ console.log("TICK"+step); break; } case 3:{ clearInterval(intervalId); phantom.exit(); } } } А от большие парсера походу не сильно удобно будет писать??? Наверно лучше делать с помощью switch чем на функции разбивать. А мб. еще есть какой то лучший способ????? Еще интересно как phantom куки сохраняет, от если я сделаю авторизацию через phantom , потом его закрой и заново открою то я буду авторизован или нет??? Нада проверить. И изображения не ясно как их копировать. От есть урл на изображение http://hsto.org/files/59f/f05/718/59...e54ea5e2b3.png и как его скопировать через phantom? просто загрузить и сохранить? Щас проверю. Хочу попробовать большой парсер написать типо товары напарсить для интернет магазина, я такой на curl писал, а тут не ясно как делать. И как прокси поменять не ясно :) |
никак изображение нимогу сохранитЬ, есть изображение http://hsto.org/files/59f/f05/718/59...e54ea5e2b3.png, загружаю его в браузер и дальше что?
вот код, загружаю страницу и сразу ошибка вылазит var webpage=require('webpage'); //var fs=require('fs'); var url="http://hsto.org/files/59f/f05/718/59ff0571875a45e79162ebe54ea5e2b3.png"; var page=webpage.create(); page.open(url,function(status){ if(status==="success"){ // page.render("img.png"); // console.log(page.content); // fs.write("img1.png",page.content,"w"); phantom.exit(); } else{ phantom.exit(); } }); Ошибка: E:\project_web\porject2>phantomjs test5.js PhantomJS has crashed. Please read the crash reporting guide at <http://phantomjs.org/crash-reporting.html> and file a bug report at <https://github.com/ariya/phantomjs/issues/new>. Please attach the crash dump file: C:\TEMP\28edde00-9364-4e54-ae01-4cb6df7a9cc8.dmp Если раскоментировать строки, то в img.png изображение но маленькое, а в img1.png испорченое изображение. Нужно как то загрузить, а как хз. Мб. как то можно изображение загрузить по ссылке с помощью просто javaScript без phantomjs???? |
Так что никто не знает как сохранить изображение спомощью javaScript???? Есть ссылка на img, нужно как то его сохранить, все ж просто :)
|
ninja2,
Это не рекурсия, разница в том, что функция выполняется асинхронно. Про сохранение изображений, глянь там есть папка examples, в ней есть похожие примеры. |
Там есть пример от тут, но он не работает пишет ошибку:
E:\project_web\porject2>phantomjs test5.js http://ariya.github.io/svg/tiger.svg tiger.png PhantomJS has crashed. Please read the crash reporting guide at <http://phantomjs.org/crash-reporting.html> and file a bug report at <https://github.com/ariya/phantomjs/issues/new>. Please attach the crash dump file: C:\TEMP\58579f65-f122-4a02-9952-41983592337a.dmp пример с тигром. Заработал с тигром, копирует, только другие копирует и добавляет лишний нивидимый размер [IMG SRC=http://f3.s.qip.ru/pQ6zADwr.png] |
когда ссылки у которых на конце png стоит то они не загружаются. Да смысл, если есть ссылка, то можно чем то другим сохранить изображение. В Phantomjs наверно любой код javaScript будет работать мб. какую то библиотеку подключить из node и сохранить.
Да что то я гуглю и ниче нету. Че JavaScript не может сохранить изображение из интернета? Я JavaScript плохо знаю, просто интересно :) . |
Ладно изображение мы не сохраним, это бесполезно, можно ссылку выводить на изображение в консоль, а из консоли считывать, фиг с ним с этим изображением.
Тут еще такие дела я сделал авторизацию на сайт fl.ru и второй раз на него захожу в phantomjs определяет что я не авторизован. Почему coocies не сохранились как в нормальном браузере???? Мне что каждый раз делать авторизацию? Ну это ужас, похоже phantomjs нужно только запускать как процесс, просто как самостоятельное приложение оно наврятли нормально работать будет. парсер так фиг нормальный напишешь или нет???? На чем вообще парсеры пишут??? Хотелось бы чтобы все было на JavaScript, а за кодировку еще забыл. Нужно ж еще и кодировку определять и если что перекодировать, в JavaScript такое есть или нет? Вообще что то javaScript убоговатый чуток :) |
Не лучше всетаки сохранить и изображение и все сделать через JS. Парсера быстро пишутся на нем, неохота смешивать, хочется все на js сделать :)
|
А почему у меня не выводятся остальные элементы после первого которые я получаю с помощью getElementsByTagName ???
var links=page.evaluate(function() { return document.getElementsByTagName('img'); }); console.log("links.length="+links.length); console.log(links[0].src);//выводится нормально console.log(links[1].src);//этот уже не выводится for(var i=0;i<links.length;i++) { console.log(i); console.log(links[1].src);//не выводится } 1 элемент выводится и зависает на console.log(links[1].src); в чем проблема???? Выводит что 10 элементов в массиве, а получаю только один, остальные виснут. Как получить все src???? Разобрался, вывел просто console.log(links[i]); и оказалось что в 0 есть [object] а в остальных null, и что делать, почему функция вернула null и 9 элементов? Как получить все изображения на странице??? querySelectorAll тоже также в первом элементе есть объект, а в 9 нету От такой код работает, когда его в конец страницы добавляю <script> var mass= document.querySelectorAll('img'); alert(mass.length); for(var i=0;i<mass.length;i++) { alert(mass[i].src); } </script> и вообще length тут 12, а у меня 10, че то evaluate не правильно как то работает. через JQuery получилось получить 10 изображений, через функции jS ниче не работает :( Короче ясно, нужно и массив в функции evaluate обходить, тогда все нормально. Наверно JavaScript функции и работать не будут вне evaluate. Какаето фигня. |
У меня так же самая проблема. Если парсю маленькие тестовые странички - всё нормально, как только большие страницы, сразу какая-то фигня, штуки 2 обработает и останавливается.
Запускаю через консоль, кто знает что и от чего это когда в консоли не решётка появляется типа user@server# а курсор мигает вот так ![]() Видите на скрине после for is end он ждёт чего-то, что бы дать команду приходится Ctrl+C нажимать и тогда уже консоль опять реагирует. Ещё не очень понятно phantom.exit где ставить правильно. Вот скрипт. var urls = [ "https://site.ru/page=1", "https://site.ru/page=2", "https://site.ru/page=3", "https://site.ru/page=4" ]; var numurls = urls.length; for (u = 0; u < numurls; u++) { var fs = require('fs'); var webPage = require('webpage'); var page = webPage.create(); console.log('link '+ urls[u]); page.open(urls[u], function(status) { console.log('Status: ' + status); if (status === 'success') { //моя обработка и запись console.log('for is end'); //phantom.exit(); } }); } // конец цикла 1 url |
Ах да ninja2, забейте на картинки, спарсите их потом на php, у меня уже есть готовый парсер, работает отлично, скорость парсинга офигенная 45 картинок за 0,3 секунды.
Phantom применять что бы картинки парсить это как-то странно короче, он для более сложных задач обычно применяется. |
Цитата:
Та уже разобрался как картинки парсить, от тут в самом низу несколько примеров, есть пример авторизации на fl.ru у тебя код может зависать потому что функции phantom.exit(); нету или бывает у меня зависало когда ошибка была в коде где то ошибка. А как через php парсить, это типо сохранить в файл ссылки и потом скопировать или как то можно из php процессы создавать? От интересно можно через php запустить консольное приложение с параметрами??? Осталось еще прокси разобрать, я что то пробовал с прокси запускать так он пол часа ждет пока прокси отработает. Это не дело. Нужно как то время засекать сколько оно будет запускаться, долго через прокси грузилось. |
Сам пока не успел опробовать но из php как-то так:
shell_exec('/usr/local/bin/phantomjs -v'); С параметром $title = shell_exec('/usr/local/bin/phantomjs /script.js http://market.yandex.ru/model.xml?modelid=8230052&hid=90594'); А вы подскажите мне как поймать этот передаваемый параметр в ЯваСкрипте? |
Цитата:
var system=require('system'); var url=system.args[1]; console.log(url); phantom.exit(); вроде так. |
По мне, так парсеры прекрасно пишутся в связке с php.
Я phantomjs использую для исполнения js кода на страницах, которые что-то генерирую динамически. Получается вполне универсальная вещь, которая и картинки умеет загружать и любую информацию доставать, даже под авторизацией. Пример вызова из php: echo shell_exec('/usr/bin/phantomjs /phantom.js http://market.yandex.ru/model.xml?modelid=8230052&hid=90594''); Пример phantom.js: "use strict"; var page = require('webpage').create(), system = require('system'), url = system.args[1]; page.open(url, function(status) { if (status === "success") { page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() { page.evaluate(function() { console.log($('h1').html()); }); phantom.exit(0); }); } else { phantom.exit(1); } }); Далее, php часть можно вставлять в любое место php парсера и тем же phpQuery разбирать полученный кусок html. Разве что для таких взятых phantomjs страниц надо отдельно авторизацию проходить, и тут, похоже, без casperjs не обойтись. Да, по моему опыту, скорость таких парсеров напрямую зависит от скорости соединения между хостингом парсера и хостингом целевого сайта, от веса страниц, от кол-ва и веса картинок, от нагруженности удаленного сайта (от того, насколько быстро он страницы отдает). Львиная доля времени уходит именно на это. |
Часовой пояс GMT +3, время: 19:00. |