Форум программистов, компьютерный форум, киберфорум
Node.js
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
10 / 10 / 1
Регистрация: 04.11.2009
Сообщений: 147

Парсинг каталога

19.03.2014, 15:51. Показов 2616. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В-общем, пишу парсер сайта, точнее каталога на сайте. Каталог представляет собой массу страниц. На первой странице - марки машин, нажимаем на марки машин - получаем все модели определенной марки, затем по определенной марке - получаем список разделов, затем наконец список деталей.
То есть, нам нужно дойти до детали - это раз, сохранить путь до детали - это два.
Начальное прохождение удобно делать через рекурсию, но в итоге переделала через последовательные вызовы одной и той же функции (что выглядит весьма некрасиво).
Проблема возникла с тем, что я не знаю сколько всего деталей у меня получилось и поэтому не получается у меня все это дело разом запихнуть в массив и отдать. Пробовала использовать async.waterfall - но он для моих целей не совсем подходит, так как аргументы не совсем последовательно идут, пробовала async.forever - не дало никаких результатов. Получается, что у меня каждый вызываемый callback порождает свою ветку выполнения.

У меня возникали идеи создать изначально дерево, а затем уже перебирать листы дерева и получать путь к ним. Но не нашла подходящего средства для деревьев на js (возможно плохо искала). Самой же реализовывать не хочется совсем.

Мне очень сильно кажется, что я написала какую-то лабуду( Но я не знаю на данный момент как написать лучше.
Пожалуйста, образумьте...
Код:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*start parsing, get main page*/
    function getMain(callback){
        request(config.get("parsers")[0].url+"catalogue.php", function (err, response, body){
            if (err){
                callback("Error in parsing "+err);
                log.error("Error in parsing");
            }else{
                callback(null, body);
        }
        })
    }
 
 
function getCats(body,str, callback){
  $ = cheerio.load(body);           
      var length = $("table.cats_table_root").length;       
            if (length>0){
                $("table.cats_table_root").find('a').each( function(){
        var t=str+this.text()+'~~';
                request(config.get("parsers")[0].url+this.attr('href'), function (err, response, body){
          callback(err, t, body);
        })}
        )}
}
 
/*parsing, get catalog's member*/
    function getCatsTable(body, str, callback){ 
      getCats(body, str, function (err,t, body){
        getCats(body, t, function (err, t, body){
          getCats(body, t, function (err, t, body){
            callback(null, t);
          })
        })
      })
    }       
        
/*catalog's elements from prods_table_root*/    
    function getProdsTable(str, callback){
                $("table.prods_table_root").find('a').each(function(){
                        var href=config.get("parsers")[0].url+this.attr("href");
                        request(href, function (err, response, body){
                            callback(null, body, href);
                        })
                })
    }
    
/*get object from str, tr(excpet tr=0, header), td, get image */                            
    function getObject(str, body, href, callback){
      $=cheerio.load(body);
      $("table.prods_table").find('tr').each(function(i, elem){
        var img=[];
                var td=[];                              
                if(i>0){                                
                    this.find('img').each(function(i,elem){
            img.push(config.get("parsers")[0].url+this.attr('src'));
          })                                    
          this.find('td').each(function(i,elem){
            td.push(this.text());
          });                                   
          var st = str.split('~~');                             
          if(st.length>=3){
            callback(null, {name:td[0], price:td[2], section:st[2], model: st[1], marka: st[0], reference: href, images:img});
          }
                }                   
      });
        }
    
  function parse(callback){
//var data=[];
    getMain(function(err,res){
      getCatsTable(res,'', function(err,str){
        getProdsTable(res, function(err,body, href){
          getObject(str, body, href, function(err,res){
//data.push(res);
            callback(null,res);
          })
        })
      });
    })
//callback(data);    //само собой получаем []
  }
 
 
  parse(function(err,res){
    console.log(res);
  });
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.03.2014, 15:51
Ответы с готовыми решениями:

Парсинг определённых страниц каталога
Здравствуйте. Написал простейший парсер, используя curl+simple_html_dom. Сначала он берёт страницу раздела сайта (в моём случае,...

Операции создания каталога, изменения временного каталога, удаление файла и директории
Написать программу, которая позволяет выполнять операции создания каталога, изменения временного каталога, удаление файла и директории...

Копирование каталога, если несколько файлов из этого каталога заняты процессом
Подскажите пожалуйста как можно скопировать каталог в котором несколько файлов заняты процессом, то бишь они не копируются... в общем мне...

8
 Аватар для nonamez123
189 / 185 / 54
Регистрация: 23.10.2010
Сообщений: 1,336
19.03.2014, 17:09
Это точно NodeJS или таки js?
0
10 / 10 / 1
Регистрация: 04.11.2009
Сообщений: 147
19.03.2014, 17:45  [ТС]
Это javascript, исполняющийся на node js
0
 Аватар для nonamez123
189 / 185 / 54
Регистрация: 23.10.2010
Сообщений: 1,336
19.03.2014, 22:49
да, парсить на nodejs.... Я бы тупо собрал бы все поля, спарсил бы финальный запрос и тупо бы подставлял значения. Данные ведь статические, зачем их парсить постоянно? Вообще пример страницы, которую нужно парсить можно? И финальный результат до кучи...
0
10 / 10 / 1
Регистрация: 04.11.2009
Сообщений: 147
19.03.2014, 23:00  [ТС]
А как вы будете определять какие поля куда относятся? И надо же страницы обойти все. Постоянно нужно обновлять данные. Собирать периодически поэтому нужно. вот каталог (не страница), которую нужно спарсить: http://zapchastuga.ru/catalogue.php
Результат нужно представить в виде объекта, который собственно есть в коде:{name:td[0], price:td[2], section:st[2], model: st[1], marka: st[0], reference: href, images:img}
0
 Аватар для nonamez123
189 / 185 / 54
Регистрация: 23.10.2010
Сообщений: 1,336
19.03.2014, 23:10
Цитата Сообщение от Sweet_Sleep Посмотреть сообщение
А как вы будете определять какие поля куда относятся?
Ну на момент поста примера не было, теперь то вижу, что там по дурному всё за 1 айди цепляется... А что нужно иметь в итоге? Список всех запчастей каталога в том порядке, в котором они там разложены?
0
10 / 10 / 1
Регистрация: 04.11.2009
Сообщений: 147
19.03.2014, 23:20  [ТС]
Просто список всех запчастей, естественно с параметрами - марка, модель, бла-бла. Порядок их в базе не важен.
0
 Аватар для nonamez123
189 / 185 / 54
Регистрация: 23.10.2010
Сообщений: 1,336
20.03.2014, 00:03
В общем-то NodeJS не для таких целей задумали, его смысл как раз в асинхронности... Попробуй привентить https://github.com/luciotato/waitfor, похоже на jQuery.when

P.S. работа примера оборвалась вот тут, не находит якорь...
JavaScript
1
$("table.prods_table_root").find('a').each(function () {
Добавлено через 8 минут
А можно слегка поговнокодить... Делаем глобальный массив для результатов и коунтер, попадая http://zapchastuga.ru/catalogu... prodid=114 мы уже знаем количество элементов, увеличиваем этот коунтер, далее всё пихаем в массив результатов. Параллельно запускаем в функции вайл, в котором с задержкой чекаем количество елементов в глобальном массиве с коунтером - когда оно станит равно, теоретически все элементы спарсены, вызываем кэллбэк... Решение конечно не фен-шуй, но и задача не торт.
1
0 / 0 / 1
Регистрация: 04.06.2014
Сообщений: 8
04.06.2014, 10:52
Sweet_Sleep, очередь не спасет? как вариант
и я не понял чем не устроила рекурсия? у меня подобное именно так и реализовано, каждая ветка каталога обрабатывается из обработки родителя, хотя сам думаю переписать все на очередь

Добавлено через 4 минуты
да, вдогонку, если это все все равно складывается в бд, то почему не делать это сразу в обработке?
как пример просто пропускать страницу через набор фильтров, которые будут определять что делать с конкретным содержимым?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.06.2014, 10:52
Помогаю со студенческими работами здесь

Дублируются при добавление элементов на одну страницу каталога на все страницы каталога
Здравствуйте. Хотелось бы узнать возможно ли добавить элементы только для одной страницы? Если у меня есть каталог товаров созданный в...

Вывести на экран содержимое каталога, размер файлов каталога, и создать новый файл
Ребята помогите создать программу на ассемблере , в которой нужно : вывести на экран содержимое каталога, размер фалов каталога, и создать...

Создание каталога, копирование файлов, архивирование содержимого каталога, запись результата работы в файл
Написать командный файл, выполняющий следующие действия: создать каталог с названием dir<дата>, где <дата> - дата, которая...

Выполнение операций создания каталога, изменения временного каталога, удаление файла и директории (рекурсивно)
пожалуйста напишите программу, которая позволяет выполнять операции создания каталога, изменения временного каталога, удаление файла и...

Рекурсивный поиск и удаление каталога. Пробелы в имени каталога
Со вторым днем зимы всех. Есть bat: @echo off rem unsvn.bat setlocal rem rdir=название_удаляемых_каталогов set rdir=Startup ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru