Извлечение многострочной строки из HTML-файла с использованием определенных тегов

Извлечение многострочной строки из HTML-файла с использованием определенных тегов

Мне нужно извлечь строку, которая начинается с тега <span class="style530">и заканчивается </span>тегом.

Я использовал команду sed, но не получил желаемого результата. Ниже приведен пример кода:

<strong>
-
<span class="style530">
AA - 
This
is my
First
Heading</span></strong><br>
<span class="style530">
<strong>
*Some
text,*
<strong>
*text*</strong>, 
*text*
<strong>
*text*</strong>: 
<br>
<span class="style530">
<strong>
- This 
is my
Second Heading</strong></span><br>
<span class="style530">
<strong>
*Some
text,*
<strong>
*text*</strong>, 
*Here
is some
text.*
<strong>*text*</strong>: 
*Here is 
some
text*.<br>
<br>
<strong>
-
<span class="style530">
- This is
my Third
Heading</span></strong><br>

Вывод должен быть таким:

 AA - This is my First Heading
 - This is my Second Heading
 - This is my Third Heading

Спасибо!

решение1

Regex на самом деле не способен полностью анализировать HTML.

Существует инструмент командной строки, который называетсяксиделькоторый позволяет использовать селекторы XPath или CSS для извлечения нужных фрагментов.

Что-то вроде этого будет соответствовать вашим требованиям:

./xidel test.html --extract '//span[@class="style530"]' --output-format bash

Но учтите, что это возвращает больше, чем требуется, так как у вас есть один незакрытый<span class="style530">

решение2

Используйте HTMLParser для таких действий:

#!/usr/bin/python
# vim: set fileencoding=utf8 :
# (c) fazie

from HTMLParser import HTMLParser
import re
import sys

class MyParser(HTMLParser):
    inside_span = False

    def __init__(self,file):
        HTMLParser.__init__(self)
        f = open(file)
        self.feed(f.read())

    def handle_starttag(self,tag,attrs):
        if tag == 'span':
            for name,value in attrs:
                if name=='class' and value=='style530':
                    self.inside_span=True

    def handle_data(self,data):
        data = data.strip(' \t\r\n')
        if data != "":
            if self.inside_span:
                data = re.sub('\n',' ',data)
                data = re.sub('\s\s+',' ',data)
                print data

    def handle_endtag(self,tag):
        if tag == 'span':
            self.inside_span=False

MyParser(sys.argv[1])

Запустить его:

python myparser.py inputfile.html

решение3

Вы можете попробовать сделать что-то вроде этого.

awk -vRS='<' '
  inside || /^span[^>]*class="style530"/ {
    inside = 1
    if (/^span/)
      n++
    else if (/^\/span>/ && !--n) {
      $0="/span>\n"
      inside=0
    }
    printf "<%s", $0
  }' file.html | sed '/^</ d' | grep -v ">$"

Однако не рекомендуется извлекать с помощью заголовков HTML. Пожалуйста, см.здесьдля того, почему вам не следует парсить HTML-страницы. Я бы посоветовал вам использовать curlи w3mудалить заголовки HTML, после чего парсинг станет немного проще.

решение4

Для простого извлечения из текстов xml/html я предпочитаю использовать xidel сCSS-селекторы.

В этом примере, чтобы выбрать все spanэлементы с атрибутом, classсодержащим слово style530, мы можем использовать

xidel --css span.style530 --xml

xidelимеет много вариантов. Ввод, предоставленный вопросом, немного шумный. В менее шумных ситуациях, с --xmlмы можем получить что-то вроде

<xml>
  <span class="style530">case 1 </span>
  <span class="menu style530 otherclass">case 2 </span>
  ...
</xml>

Связанный контент