La búsqueda de contenido entre dos palabras sin expresiones regulares, BeautifulSoup, LXML ... etc.

StackOverflow https://stackoverflow.com/questions/1116172

  •  12-09-2019
  •  | 
  •  

Pregunta

Cómo averiguar el contenido entre dos palabras o dos conjuntos de caracteres al azar?

La página raspado no se garantiza que sea sólo HTML y los datos importantes pueden estar dentro de un bloque de Javascript. Por lo tanto, no puedo quitar el JavaScript.

considere esto:

<html>
<body>
<div>StartYYYY "Extract HTML", ENDYYYY

</body>

Some Java Scripts code STARTXXXX "Extract JS Code" ENDXXXX.

</html>

Así que como ves el código HTML puede no ser completa. Que puedo pedir a la página, y luego sin preocuparse de nada, quiero encontrar el contenido llamado "Extraer el nombre" y "extraer los datos aquí en un JavaScript".

Lo que yo busco es en python:

De esta manera:

data = FindBetweenText(UniqueTextBeforeContent, UniqueTextAfterContent, page)

Cuando la página está descargado y datos tendría el texto que estoy buscando. Yo prefiero quedarme lejos de expresiones regulares como algunos de los casos puede ser demasiado complejo para expresiones regulares.

¿Fue útil?

Solución

Aquí está mi intento, esto se prueba. Mientras recursivo, no debería haber ninguna duplicación innecesaria de cadena, aunque un generador podría ser más óptima

def bracketed_find(s, start, end, startat=0):
    startloc=s.find(start, startat)
    if startloc==-1:
        return []
    endloc=s.find(end, startloc+len(start))
    if endloc == -1:
        return [s[startloc+len(start):]]
    return [s[startloc+len(start):endloc]] + bracketed_find(s, start, end, endloc+len(end))

y aquí es una versión del generador

def bracketed_find(s, start, end, startat=0):
    startloc=s.find(start, startat)
    if startloc==-1:
        return
    endloc=s.find(end, startloc+len(start))
    if endloc == -1:
        yield s[startloc+len(start):]
        return
    else:
        yield s[startloc+len(start):endloc]

    for found in bracketed_find(s, start, end, endloc+len(end)):
        yield found

Otros consejos

si está seguro de sus marcadores son únicos, hacer algo como esto

s="""
<html>
<body>
<div>StartYYYY "Extract HTML", ENDYYYY

</body>

Some Java Scripts code STARTXXXX "Extract JS Code" ENDXXXX.

</html>
"""

def FindBetweenText(startMarker, endMarker, text):
    startPos = text.find(startMarker)
    if startPos < 0: return
    endPos = text.find(endMarker)
    if endPos < 0: return

    return text[startPos+len(startMarker):endPos]

print FindBetweenText('STARTXXXX', 'ENDXXXX', s)

Bueno, esto es lo que sería en PHP. No hay duda de que hay una manera mucho más sexy Pythonic.

function FindBetweenText($before, $after, $text) {
    $before_pos = strpos($text, $before);
    if($before_pos === false)
        return null;
    $after_pos = strpos($text, $after);
    if($after_pos === false || $after_pos <= $before_pos)
        return null;
    return substr($text, $before_pos, $after_pos - $before_pos);
}

[Ligeramente probado]

def bracketed_find_first(prefix, suffix, page, start=0):
    prefixpos = page.find(prefix, start)
    if prefixpos == -1: return None # NOT ""
    startpos = prefixpos + len(prefix)
    endpos = page.find(suffix, startpos) # DRY
    if endpos == -1: return None # NOT ""
    return page[startpos:endpos]

Nota: sólo los rendimientos por encima de la primera aparición. Aquí es un generador que produce cada ocurrencia.

def bracketed_finditer(prefix, suffix, page, start_at=0):
    while True:
        prefixpos = page.find(prefix, start_at)
        if prefixpos == -1: return # StopIteration
        startpos = prefixpos + len(prefix)
        endpos = page.find(suffix, startpos)
        if endpos == -1: return
        yield page[startpos:endpos]
        start_at = endpos + len(suffix)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top