Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Ручной парсинг HTML файла / 25 сообщений из 35, страница 1 из 2
08.03.2017, 01:25
    #39415746
Natalia_141277
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Добрый день!
Учебное задание: нужно распарсить HTML файл, удалив из него все теги, оставить только контент.
Задание надо сделать вручную. Пыталась парсить с помощью regex, получается какой-то бред, т.к. в файле есть span, вложенные в div и подогнать нужный текст под шаблон не получается, т.к. span открывается, закрывается и не открывшись повторно, опять закрывается.

<span style="white-space: pre-line" class='instruction__description js-steps__description _no-photo'><span>5. </span>НУЖНЫЙ ТЕКСТ</span>

Pattern pattern = Pattern.compile(<(a|span|div|p|h?)[^>]*>(?<content>[^<]*)</(a|span|div|p|h?)>);
Matcher matcher = pattern.matcher(htmlDocument);
while (matcher.find()) {
System.out.println(matcher.group());
doc = matcher.group();
}

Перебирать посимвольно и удалять символы после того, как найдет открытый тег "<" искать закрытый ">" и удалять весь тег - по-моему так некорректно, в файле же могут быть математические знаки <>.Кроме того, при посимвольном парсинге с сайта выдается ошибка StringIndexOutOfBoundsException....Если загнать часть текста в переменную, то пасрится более-менее, но с учетом некорректности из-за возможного наличия математических знаков в тексте.

while (i < htmlDocument.length()) {
if (htmlDocument.charAt(i) == '<') {
isTag = true;
while (isTag) {
if (htmlDocument.charAt(i+1)=='!')
if (str.charAt(i) == '>') {
isTag = false;
}
i++;
}
} else {
stringList.add((String.valueOf(str.charAt(i))));
i++;
}
}
Кроме того, при посимвольном парсинге выдается ошибка StringIndexOutOfBoundsException....
Что-то я совсем запуталась, может быть кто-то делал что подобное, подскажите пожалуйста!:-)
Спасибо большое!
...
Рейтинг: 0 / 0
08.03.2017, 21:39
    #39415946
Dmitry.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
выкинуть теги - как-то так
Код: java
1.
s.replaceAll("(?:<style.+?>.+?</style>|<script.+?>.+?</script>|<(?:!|/?[a-&#8204;&#8203;zA-Z]+).*?/?>)","");



надо еще флаги поставить типа mutiline, dotall,...
...
Рейтинг: 0 / 0
09.03.2017, 11:39
    #39416054
SQL2008
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Навскидку
Код: html
1.
Pattern pattern = Pattern.compile(<(a|span|div|p|h?)[^>]*>(?<content>[^<]*)</(a|span|div|p|h?)>);


table,tr,td тэги вы полагаете там не встречаются?
...
Рейтинг: 0 / 0
09.03.2017, 12:58
    #39416119
programania
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Natalia_141277нужно распарсить HTML файл, удалив из него все теги, оставить только контент.

Код: java
1.
2.
3.
s="<span style=\"white-space: pre-line\" class='instruction__description js-steps__description _no-photo'><span>5. </span>НУЖНЫЙ ТЕКСТ</span>";
s=s.replaceAll("</?.+?>","");
// s == "5. НУЖНЫЙ ТЕКСТ"


Natalia_141277с учетом некорректности из-за возможного наличия математических знаков в тексте.

Если текст в html, то вместо <> используются коды & l t ; и & g t ; иначе и браузер не поймет.
...
Рейтинг: 0 / 0
09.03.2017, 14:57
    #39416242
Natalia_141277
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Dmitry.,

спасибо, а флаги для чего? я не спец, сорри за уточнение:-)
разве мы по этой формуле не только script теги откидываем?
просто мне надо теги без текста (контента внутри) откинуть, а из остальных получить контент (нужный текст с сайта), т.е. span|div et. надо оставить, чтобы получить текст, script-ы удалить полностью
а это перебором посимвольно можно сделать?
спасибо за ответ!:-)
...
Рейтинг: 0 / 0
09.03.2017, 14:58
    #39416244
Natalia_141277
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
SQL2008,

спасибо за уточнение, добавлю, а дальше как оттуда текст получить?:-)
...
Рейтинг: 0 / 0
09.03.2017, 15:00
    #39416247
Natalia_141277
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
programania,

спасибо большое за уточнение:-)
часть проблемы снята:-)
посимвольно это можно распарсить или с regex лучше?
нам дали задание еще с помощью Enum попробовать, что эффективнее?
спасибо!
...
Рейтинг: 0 / 0
09.03.2017, 18:28
    #39416420
programania
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Natalia_141277посимвольно это можно распарсить или с regex лучше?

Посимвольно раз в 20 длиннее, не наглядно и не надежно, но может быть быстрее regex,
т.к. regex в java на чистой java.
С regex можно еще короче: s=s.replaceAll("<.+?>","");

Natalia_141277нам дали задание еще с помощью Enum попробовать, что эффективнее?

Эффективность предсказать невозможно. Только через System.nanoTime()
...
Рейтинг: 0 / 0
09.03.2017, 18:56
    #39416436
Natalia_141277
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
programaniaNatalia_141277посимвольно это можно распарсить или с regex лучше?

Посимвольно раз в 20 длиннее, не наглядно и не надежно, но может быть быстрее regex,
т.к. regex в java на чистой java.
С regex можно еще короче: s=s.replaceAll("<.+?>","");

Natalia_141277нам дали задание еще с помощью Enum попробовать, что эффективнее?

Эффективность предсказать невозможно. Только через System.nanoTime()

s=s.replaceAll("<.+?>",""); - не подходит, т.к. так останется то, что в тегах script между <script>.....</script>.

А regex можно как-то к Enum привязать, например, Enum типа String, в String засунуть regex и потом парсить по CASE?
Или это лишнее?
...
Рейтинг: 0 / 0
09.03.2017, 23:42
    #39416518
TREY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
достаточно весь текст впихнуть в строку, и в строке сделать замену <.*?> на " ".
Потом сделать замену \s+ на " " что бы убрать лишнее пустое место
...
Рейтинг: 0 / 0
10.03.2017, 00:09
    #39416524
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Natalia_141277, регуляркой эту задачу тоже можно решать.

Но под конец она будет настолько сложна что ее будет невозможно
не только дебажить но и просто осмыслить.

Разумнее разбить весь процесс на какие-то фазы трансформаций
типа:
1) Очистка и декодирование кодировок.
2) Удаление jscript
3) Удаление тегововой разметки, каментов.
4) Де-эскейпинг &-последовательностей, entities, CDATA
...
Рейтинг: 0 / 0
10.03.2017, 00:39
    #39416529
programania
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Natalia_141277s=s.replaceAll("<.+?>",""); - не подходит, т.к. так останется то, что в тегах script между <script>.....</script>.
В Учебном задании про script ничего не сказано:
"Учебное задание: нужно распарсить HTML файл, удалив из него все теги, оставить только контент."

Если учитывать что там еще не сказано, то может получиться такое:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
try {
  JOptionPane.showMessageDialog(null,
    new Scanner((new URL("http://www.sql.ru/forum/1252531/ruchnoy-parsing-html-fayla" )).openStream(),"Cp1251").useDelimiter("\\Z").next()
        .replaceAll("(?s)<!--.+?-->|<script.+?</script>|<.+?>","")
        .replaceAll("&nbsp;|  +"," ")
        .replaceAll("\r\n ","\r\n")
        .replaceAll("[\r\n\t]+","\r\n")
  );
} catch (Exception e){}
...
Рейтинг: 0 / 0
10.03.2017, 13:30
    #39416870
SQL2008
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
programania, вы забыли про кучу иных спецсимволов
Я реализовал это так. Кстати здесь еще не все, а только те, что встречались в моем HTML.
Код: java
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.
  public String symbolsReplace(String html){
    Map<String,String> map = new HashMap<String, String>();
      map.put("&quot;", "\"");
      map.put("&amp;", "&");
      map.put("&lt;", "<");
      map.put("&gt;", ">");
      map.put("&circ;", "&#710;");
      map.put("&tilde;", "&#732;");
      map.put("&nbsp;", " ");
      map.put("&ndash;", "–");
      map.put("&mdash;", "—");
      map.put("&lsquo;", "‘");
      map.put("&rsquo;", "’");
      map.put("&sbquo;", "‚");
      map.put("&ldquo;", "“");
      map.put("&laquo;", "[");
      map.put("&raquo;", "]");
      map.put("&rdquo;", "”");
      map.put("&bdquo;", "„");
 
      for(Map.Entry<String, String> item : map.entrySet()){       
             html = html.replace(item.getKey(), item.getValue());
         }
return htm;
}
...
Рейтинг: 0 / 0
10.03.2017, 13:31
    #39416872
SQL2008
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
return html;
...
Рейтинг: 0 / 0
10.03.2017, 18:12
    #39417150
programania
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
SQL2008programania, вы забыли про кучу иных спецсимволов
Я не забыл, но их там сотни, поэтому все писать не стал.
В случае многочисленных замен лучше оформить это максимально наглядно и коротко.
Например, в вашем примере вместо map.put(" ", " "); можно было бы сразу replace().replace()....
если, конечно, это не "Учебное задание" где надо непременно показать знание Map.
Я бы оформил это как замены по таблице:
Код: java
1.
2.
3.
4.
5.
6.
7.
String[] t=(
   "&quot;  \"       &amp;   &    &lt;    <    &gt;    >    &circ;  &#710;   &tilde; &#732 " +
   "&nbsp;  пробел   &ndash; –    &mdash; —    &lsquo; ‘    &rsquo; ’        &sbquo; ‚     " +
   "&ldquo; “        &laquo; [    &raquo; ]    &rdquo; ”    &bdquo; „        <br>    \r\n  "
).split(" +");
for (int i=0; i<t.length; i+=2)
     html = html.replace(t[i],  t[i+1].replace("пробел"," "));
...
Рейтинг: 0 / 0
11.03.2017, 01:30
    #39417262
Natalia_141277
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
mayton,

правильно все логично, но только надо уложиться в максимально короткое время, идеально - в один цикл, два - уже хуже...
спасибо за совет!:-)
...
Рейтинг: 0 / 0
11.03.2017, 01:33
    #39417263
Natalia_141277
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
TREY,

если бы все было так просто, это бы не было учебным заданием и я бы не задавала тут вопросы:-)

1.) комменты в тегах пропадут при таком парсинге;
2.) спецсимволы не распарсятся.

как минимум 2 проблемы...:-)
...
Рейтинг: 0 / 0
11.03.2017, 01:39
    #39417264
Natalia_141277
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
programania,

спасибо большое, вы очень помогли!;-)
особенно была проблема с возможными математическими знаками "<>", которые я вообще не представляла как парсить:-)
ну как и компилятор собственно:-)
...
Рейтинг: 0 / 0
11.03.2017, 01:43
    #39417266
Natalia_141277
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
SQL2008,

спасибо большое!:-)

C HashMap отличная идея, заброшу их все в отдельный класс и оттуда можно парсить,
а полный перечень есть где-то? может библиотека спецсимволов HTML какая-то?
И ее можно как-то в проект подтянуть, чтоб не делать отдельный класс.
...
Рейтинг: 0 / 0
11.03.2017, 06:34
    #39417278
SQL2008
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Natalia_141277 а полный перечень есть где-то? может библиотека спецсимволов HTML какая-то?
Да пожалуйста .
...
Рейтинг: 0 / 0
11.03.2017, 06:35
    #39417279
SQL2008
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Или вот еще .
...
Рейтинг: 0 / 0
12.03.2017, 16:51
    #39417617
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Natalia_141277...
Учебное задание: нужно распарсить HTML файл, удалив из него все теги, оставить только контент.
Задание надо сделать вручную. Пыталась парсить с помощью regex, получается какой-то бред, ...

А слова "конечный автомат" уже в институтах/техникумах/ПТУ не проходят?

Подозреваю, пытаться нужно так, как учил преподаватель на лекциях. А иначе, вне зависимости от кода - "получится какой-то бред" на зачете/экзамене.

IMHO & AFAIK
...
Рейтинг: 0 / 0
12.03.2017, 16:57
    #39417618
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
maytonNatalia_141277, регуляркой эту задачу тоже можно решать.

Но под конец она будет настолько сложна что ее будет невозможно
не только дебажить но и просто осмыслить.

Назвать "решение регуляркой" - парсингом. Лично у меня язык не поворачивается

maytonРазумнее разбить весь процесс на какие-то фазы трансформаций
типа:
1) Очистка и декодирование кодировок.
2) Удаление jscript
3) Удаление тегововой разметки, каментов.
4) Де-эскейпинг &-последовательностей, entities, CDATA
Нафига делать 100500 каких-то "фаз трансформации", когда все это элементарно вытягивается за один проход нормальным парсером в виде конечного автомата?
...
Рейтинг: 0 / 0
12.03.2017, 17:00
    #39417619
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
IMHO Вирт как автор мне не очень нравится (((, но по теме топика сразу вспоминается:

https://www.ozon.ru/context/detail/id/135695723/

Ну и я бы какие нибудь книжки по словам "теория конечных автоматов" поискал. Сам читал лет 20 назад, т.ч. ничего рекомендовать не могу.
...
Рейтинг: 0 / 0
12.03.2017, 17:36
    #39417633
Natalia_141277
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ручной парсинг HTML файла
Leonid Kudryavtsev,
Спасибо, почитаю, пока сделала так, или это очень упрощенно?
Спасибо!

Код: java
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.
public class ParseHtml {
        public String symbolsReplacement(String htmlDocument) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("&quot;", "\"");
            map.put("&amp;", "&");
            map.put("&lt;", "<");
            map.put("&gt;", ">");
            map.put("&nbsp;", " ");
            map.put("&ndash;", "–");
            map.put("&mdash;", "—");
            map.put("&lsquo;", "‘");
            map.put("&rsquo;", "’");
            map.put("&sbquo;", "‚");
            map.put("&ldquo;", "“");
            map.put("&laquo;", "[");
            map.put("&raquo;", "]");
            map.put("&rdquo;", "”");
            map.put("&bdquo;", "„");
            map.put("&frac14;","1/4");
            map.put("&frac12;","1/2");
            map.put("&frac34;","3/4");
            map.put("&copy;","©");
            map.put("&bull;",".");
            map.put("&#8209;","-");

            for (Map.Entry<String, String> item : map.entrySet()) {
                htmlDocument = htmlDocument.replace(item.getKey(), item.getValue());
            }
            return htmlDocument;
        }

        public String parseHtmlDoc(String htmlDocument) {
            StringBuilder resultedDocument = new StringBuilder();
            Stack<Tags> tag = new Stack<>();
            tag.push(Tags.TEXT_BETWEEN_TAGS);
            char temp;
            for (int i = 0; i < htmlDocument.length(); i++) {
                temp = htmlDocument.charAt(i);
                if (temp == '<' && htmlDocument.charAt(i + 1) == 's' && htmlDocument.charAt(i + 2) == 'c' && htmlDocument.charAt(i + 3) == 'r') {
                    tag.push(Tags.SCRIPT_TAG);
                    continue;
                }
                if (temp == '<' && htmlDocument.charAt(i + 1) == '/' && htmlDocument.charAt(i + 2) == 's' && htmlDocument.charAt(i + 3) == 'c') {
                    tag.pop();
                    i = i + 8;
                    continue;
                }
                if (tag.peek() == Tags.SCRIPT_TAG) {
                    continue;
                }
                if (temp == '<' && htmlDocument.charAt(i + 1) == 's' && htmlDocument.charAt(i + 2) == 't' && htmlDocument.charAt(i + 3) == 'y') {
                    tag.push(Tags.STYLE_TAG);
                    continue;
                }
                if (temp == '<' && htmlDocument.charAt(i + 1) == '/' && htmlDocument.charAt(i + 2) == 's' && htmlDocument.charAt(i + 3) == 't') {
                    tag.pop();
                    i += 7;
                    continue;
                }
                if (tag.peek() == Tags.STYLE_TAG) {
                    continue;
                }
                if (temp == '<' && (tag.peek() != Tags.SCRIPT_TAG || tag.peek() != Tags.STYLE_TAG)) {
                    tag.push(Tags.OTHER_TAG);
                    continue;
                }
                if (temp == '>' && tag.peek() == Tags.OTHER_TAG) {
                    tag.pop();
                    continue;
                }
                if (tag.peek() == Tags.TEXT_BETWEEN_TAGS) {
                    if (temp == ' ' && (resultedDocument.length() == 0 || resultedDocument.charAt(resultedDocument.length() - 1) == ' '))
                        continue;
                    resultedDocument.append(temp);
                }
            }
            return (resultedDocument.toString()).replaceAll("[\\s]{2,}", " ");
        }
    }
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Ручной парсинг HTML файла / 25 сообщений из 35, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]