Форум русскоязычного сообщества Ubuntu


Автор Тема: экспорт из html  (Прочитано 3926 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн lead

  • Автор темы
  • Новичок
  • *
  • Сообщений: 21
    • Просмотр профиля
экспорт из html
« : 02 Апреля 2016, 18:17:15 »
Добрый день всем участникам!

Суть задачи - есть много (около 4.000) файлов html, структура одинаковая, нужно из каждого файла экспортировать текст в какой-нибудь формат для дальнейшей сортировки (xls, csv, odt - не столь важно).

Пример кода: <b class="worker">Виктор</b>, вот нужно только этого "Виктора" и экспортировать.

Хотелось бы найти готовое решение/программу, все мысли почему-то крутятся в заказе скрипта-обработчика на php...

Заранее спасибо за советы )
пришло время переустановить шындос

serchik

  • Гость
Re: экспорт из html
« Ответ #1 : 02 Апреля 2016, 18:29:02 »
Пишите скрипт на python (или любом другом языке на ваш выбор  ;)) + html/xml parser + xslt

Оффлайн lead

  • Автор темы
  • Новичок
  • *
  • Сообщений: 21
    • Просмотр профиля
Re: экспорт из html
« Ответ #2 : 02 Апреля 2016, 18:41:45 »
Оно-то понятно, но может быть есть какие-то готовые инструменты?  ;) Задача-то вполне тривиальная - по сути - работа с текстом.
пришло время переустановить шындос

Оффлайн zotkindm

  • Старожил
  • *
  • Сообщений: 2452
  • (K)Ub 14.04
    • Просмотр профиля
Re: экспорт из html
« Ответ #3 : 02 Апреля 2016, 18:47:38 »
скрипт
                   цикл
                   поиск искомой фразы
                   вывод в txt
                   завершение цикла
конц скрипта
копай в сторону grep
для начала попробуй типа cat 'file' | grep 'выборка' > 'выходной файл' , если сработала, запили цикл, в bash скрипте.
« Последнее редактирование: 02 Апреля 2016, 18:51:48 от zotkindm »

serchik

  • Гость
Re: экспорт из html
« Ответ #4 : 02 Апреля 2016, 19:10:16 »
Оно-то понятно, но может быть есть какие-то готовые инструменты?  ;) Задача-то вполне тривиальная - по сути - работа с текстом.
Ну и скрипт тоже тривиальный. :) Не найдете решения в ближайшие 3-4 дня (раньше буду занят), пишите в личку, напишу Вам скрипт.

Оффлайн lead

  • Автор темы
  • Новичок
  • *
  • Сообщений: 21
    • Просмотр профиля
Re: экспорт из html
« Ответ #5 : 02 Апреля 2016, 19:28:52 »
Спасибо огромное, просто сложнее формы связи на PHP ничего не писал  ;D

Пока, по совету zotkindm курю grep, идея вполне здравая.
пришло время переустановить шындос

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: экспорт из html
« Ответ #6 : 02 Апреля 2016, 21:24:08 »
lead, есть и консольные парсеры xml/html работающие по принципу grep|sed
Код: (html5) [Выделить]
html-xml-utils - Утилиты для работы с HTML и XML
xml2 - Convert between XML, HTML, CSV and a line-oriented format
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн lead

  • Автор темы
  • Новичок
  • *
  • Сообщений: 21
    • Просмотр профиля
Re: экспорт из html
« Ответ #7 : 07 Апреля 2016, 12:00:55 »
Azure, пока остановился на Ruby-парсере Nokogiri, его функционал интересен тем, что он умеет парсить по css-селекторам. Сижу вот, курю маны :)
пришло время переустановить шындос

Оффлайн jura12

  • Старожил
  • *
  • Сообщений: 1411
  • 20.04
    • Просмотр профиля
Re: экспорт из html
« Ответ #8 : 07 Апреля 2016, 12:37:32 »
сопротивление бесполезно

Оффлайн lead

  • Автор темы
  • Новичок
  • *
  • Сообщений: 21
    • Просмотр профиля
Re: экспорт из html
« Ответ #9 : 07 Апреля 2016, 13:06:53 »
jura12, спасибо, не знал ранее.

Прошу не гнать тряпками, про мои познания php уже писал, чукча не писатель скриптов, он их выполнятель ;D

Код: (php) [Выделить]
<?php
$html 
file_get_html('home/user/1.html');
echo 
strip_tags(".myclass");
$html->clear();
unset(
$html);
?>

По-идее выведет содержание

Код: (html5) [Выделить]
тут многакода
<div id="35" class="myclass">Привет форум</div>
тут еще чего-то написали

в виде "Привет форум" ? Или выведет весь html как есть, а "Привет форум" почистит от тегов?

А если таких "приветфорумов" с одинаковым классом на странице два? Оба выведет? Или только первый, а значит надо еще какой-то цикл в php добавить?

Под рукой нет Apache чтобы проверить самому, может до вечера кто что насоветует
« Последнее редактирование: 07 Апреля 2016, 13:28:31 от lead »
пришло время переустановить шындос

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Re: экспорт из html
« Ответ #10 : 07 Апреля 2016, 18:02:44 »
Есть команда

sudo apt-get install regina-rexx

После нее такой скрипт:

#!/usr/bin/rexx

FILE = 'myfile.html'
START = '<div id="35" class="myclass">'
STOP = '</div>'

do while lines(FILE) > 0
 A1 = linein(FILE)

 parse var A1 (START) A2
 parse var A2 OUR_TEXT (STOP)

 if OUR_TEXT \= '' then say OUR_TEXT
end

обработает ваш файл так:
1) прочитает по строкам
2) Для каждой строки, если в ней есть «<div id="35" class="myclass">», «</div>» и что-то между ними, напечатает это «что-то»
3) Если есть только «<div id="35" class="myclass">» или только «</div>», то ничего не напечатает.

Естественно, более сложные обработки текста требуют больших усилий, но в целом, если надо по-быстрому выдрать из html какую-либо инфу, не особо разбираясь в структуре, — самый тот язык.

Могу этот скриптик снабдить построчными комментариями, если интересно.
« Последнее редактирование: 07 Апреля 2016, 18:18:56 от inkblack »
Делюсь знаниями, но их у меня мало!

Оффлайн lead

  • Автор темы
  • Новичок
  • *
  • Сообщений: 21
    • Просмотр профиля
Re: экспорт из html
« Ответ #11 : 07 Апреля 2016, 18:50:18 »
Огромное спасибо, inkblack!

Прокомментировать, наверное, попытаюсь сам, чтобы понять логику и меньше дергать людей в схожих ситуациях, не уверен что получится  ;D

Код: (php) [Выделить]
#!/usr/bin/rexxэто понятно, где он у нас находится

Код: (php) [Выделить]
FILE = 'myfile.html'
START = '<div id="35" class="myclass">'
STOP = '</div>'
тут тоже ясно - имя/путь нужного файла + область в которой скрипт срабатывает

Код: (php) [Выделить]
do while lines(FILE) > 0
 A1 = linein(FILE)
видимо проверка, что возвращается не пустота. Вернее, если в возврате что-то есть - то передать в работу

Код: (php) [Выделить]
parse var A1 (START) A2
 parse var A2 OUR_TEXT (STOP)
это границы парсинга

Код: (php) [Выделить]
if OUR_TEXT \= '' then say OUR_TEXTесли в выводе что-то есть, то это и есть наш текст, который надо вывести

Литературы под рукой нет, писал из головы, ногами не бейте  :-[



пришло время переустановить шындос

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Re: экспорт из html
« Ответ #12 : 07 Апреля 2016, 19:36:09 »

    do while lines(FILE) > 0  -- lines(FILE) - это сколько еще непрочитанных строк осталось в файле.
                              -- если строк больше нет, то возвращается 0, если есть, то 1 или реальное
                              -- количество строк, допустим 8, в зависимости от настроек.
                              -- Таким образом, этот цикл (до end) выполняется, пока в файле есть строки

     A1 = linein(FILE)        -- читает очередную строку в переменную A1


parse — одна из двух МЕГАфишек этого языка. Делит строку в соответствии с образцами.
например:
parse var TEXT . '[[' NOTE ']]' .
1     2   3    4 5    6    7    8

1 — ключевое слово, начинающее оператор «разбора строки»
2 — ключевое слово, сообщающее, что дальше идет имя переменной, которую будем разбирать.
3 — имя переменной, в которой лежит строка, которую разбираем.
4 — точка — placeholder, означает, что всё, что до первого образца, отбрасывается и не используется.
5 — образец; разбираемая строка делится на «всё, что до» и «всё, что после». Всё, что до, отбрасывается (пункт 4).
6 — имя переменной, в которую складываем то, что после первого образца, но до второго.
7 — второй образец
8 — то, что после второго образца идет в эту точку, то есть отбрасывается.

и из  'text text [[примечание]] other text'
мы получаем  'примечание'.  Всё, что до '[[' и после ']]' — отбрасывается.

это простейший пример, здесь, если второй образец в строке отсутствует, то в  NOTE  попадает всё, что до конца строки. Поэтому в предыдущем примере я использовал 2 оператора  parse

Пользователь добавил сообщение 07 Апреля 2016, 19:49:59:
Естественно, если есть 4000 файлов, то можно в скрипте получить их список, а потом для каждого элемента из списка проделать нужные процедуры разбора.
« Последнее редактирование: 07 Апреля 2016, 19:49:59 от inkblack »
Делюсь знаниями, но их у меня мало!

Оффлайн lead

  • Автор темы
  • Новичок
  • *
  • Сообщений: 21
    • Просмотр профиля
Re: экспорт из html
« Ответ #13 : 07 Апреля 2016, 19:56:23 »
inkblack, ну это, в приниципе, то, что нужно!

Я несколько сумбурно объяснил что меня интересует, если честно даже не ожидал такого участия форума, но раз так - поподробнее.

На сегодня имеется очень много (точно не пересчитывал, но в районе 4.000) html, выполненных по одной маске.

Код: (html5) [Выделить]
<div class="заголовок">1 июня 2005</div>
далее код, в нем помимо прочего
<div class="ученик"><span>Ваня Иванов</span></div>
<div id=613 class="оценка">99 баллов</div>
далее еще код, в нем ниже
<div class="ученик"><span>Петя Петров</span></div>
<div id=904 class="оценка">87 баллов</div>
потом еще много кода, в среднем на странице по 10 учеников и, соответственно, столько же оценок

id везде разный, взятый вообще с потолка, без какой-либо взаимосвязи. Именно поэтому и думаю над тем, чтобы привязаться к классам css.

Почему так косо все делалось изначально я не знаю, но видимо была причина. Цель - выдрать заголовок, имя и оценку во что-то более вменяемое - хоть libre calc, хоть что-то, окончательная цель - создание базы MYSQL с дальнейшим администрирванием.

Тоесть вид строки - заголовок, имя, баллы;
первая строка - 1 июня 2005, Ваня Иванов, 99 баллов
вторая строка - 1 июня 2005, Петя Петров, 86 баллов
 
Причем заголовок в документе упоминается только единожды, а получается, что его нужно подставить в каждую строку.

Короче голова уже плавится, наверное пока я освою парсинг - уже бы вручную все перевел  :2funny:   

Моя логика такова:
- количеством файлов пока голову не забиваем, это второй вопрос, или конвейер построю, или скрипт обработчик скрипта обработчика, или вообще по-хардкору сошью все 4.000 файлов в один гигантский  :idiot2:
- заголовок не меняется, стало быть можно его сделать какой-либо константой, присвоить значение единожды и все
- а вот дальше хз, ступор
« Последнее редактирование: 07 Апреля 2016, 19:59:54 от lead »
пришло время переустановить шындос

Оффлайн inkblack

  • Старожил
  • *
  • Сообщений: 1216
    • Просмотр профиля
Re: экспорт из html
« Ответ #14 : 07 Апреля 2016, 20:19:25 »
Щас сделаем

Пользователь добавил сообщение 07 Апреля 2016, 21:37:50:
Как-то так:
Код: (PHP) [Выделить]
#!/usr/bin/rexx
                                                                             /*
   Всё это будет работать так, как задумано, если:
   1) <div class="заголовок">1 июня 2005</div> — на одной строке,
      без переносов, ДИВы и классы в точности, как здесь, с точностью до
      количества пробелов.
   2) <div class="ученик"><span>Ваня Иванов</span></div> — на одной строке,
      без переносов, ДИВы и классы в точности, как здесь, с точностью до
      количества пробелов.
   3) <div id=904 class="оценка">87 баллов</div> — тоже на одной строке.
      В этой строке «<div id=904» мы игнорируем, начинаем распознавать с
      « class="оценка">».
   4) Здесь мы распознаем 3 типа строк:
      - <div class="заголовок">1 июня 2005</div>
      - <div class="ученик"><span>Ваня Иванов</span></div>
      - <div id=613 class="оценка">99 баллов</div>
      Все остальные данные игнорируются.
      Предполагается, что в читаемом файле сначала встречается строка
      ПЕРВОГО типа, потом встречается строка ВТОРОГО типа, потом ТРЕТЬЕГО,
      потом опять ВТОРОГО, ТРЕТЬЕГО и т. д.                                  */

 FILE   = 'source.html'

 DAT_01 = '<div class="заголовок">'
 DAT_02 = '</div>'
 NAM_01 = '<div class="ученик"><span>'
 NAM_02 = '</span></div>'
 SCO_01 = ' class="оценка">'
 SCO_02 = '</div>'

 ADATE = '<NO_DATE>'                     -- На всякий случай. Если в выводе
 ANAME = '<NO_NAME>'                     -- появится это, значит, что-то
 SCORE = '<NO_SCORE>'                    -- не то в формате файла.

 TAB = d2c(9)                            -- символ с кодом 9, т.е. табуляция

 do while lines(FILE) > 0
  A1 = linein(FILE)

  if pos(DAT_01, A1)>0 & pos(DAT_02, A1)>0 then    -- в этой строке дата,
   parse var A1 (DAT_01) ADATE (DAT_02)            -- достаём её.

  if pos(NAM_01, A1)>0 & pos(NAM_02, A1)>0 then    -- в этой строке имя,
   parse var A1 (NAM_01) ANAME (NAM_02)            -- достаём его.

  if pos(SCO_01, A1)>0 & pos(SCO_02, A1)>0 then do -- в этой строке оценка,
   parse var A1 (SCO_01) SCORE (SCO_02)            -- достаём её...
   say ADATE || TAB || ANAME || TAB || SCORE       -- и печатаем дату имя оценку
                                                                             /*
   Вот это еще я добавил на всякий случай: после того, как оценка напечатана,
   мы обнуляем имя, поэтому, если дальше встретится опять оценка, а не имя,
   в выводе сразу будет видно, что ЧТО-ТО ПОШЛО НЕ ТАК.                      */

   ANAME = '<NO_NAME>'

  end

 end /* while lines(FILE) */

Вообще, Rexx очень хорош для подобных пятиминутных скриптов «на коленке».
В то же время, если не лениться, писать аккуратно, не пренебрегать комментариями —
можно создать очень полезную программку, которой потом пользоваться будете долгие годы и с удовольствием.

Удачи!

Пользователь добавил сообщение 07 Апреля 2016, 22:11:44:
В общем-то надо бы описать основную идею.

Есть файл. в нем есть 4 типа строк:
1) Заголовок.
2) Ученик.
3) Оценка.
4) Ненужная информация.

Каждая строка может быть только одного типа.
Читаем строки по одной. Проверяем.

— Если строка типа Заголовок, запоминаем заголовок.
— Если строка типа Ученик, запоминаем имя.
— Если строка типа Оценка, тогда печатаем:
заголовок (он должен был встретиться раньше и мы его уже запомнили),
имя (оно тоже уже встретилось раньше и мы его тоже запомнили)
оценку. И после этого «обнуляем» имя, чтобы хоть как-то проверить
правильность входного файла.
(Нажмите, чтобы показать/скрыть)

— Если строка типа Ненужная информация, то не делаем ничего,
а переходим к чтению следующей строки.

« Последнее редактирование: 07 Апреля 2016, 22:17:54 от inkblack »
Делюсь знаниями, но их у меня мало!

 

Страница сгенерирована за 0.039 секунд. Запросов: 26.