Limita de adâncime tag.text

voturi
0

Pur și simplu nu pot obține dreptul. BeautifulSoup4 este atât de confuz.

Am încercat să stabilească referințe Markdown netopite în text HTML. Regex este:

REF = re.compile(r\[(?P<title>.+?)\]\[(?P<identifier>.*?)\])

Deoarece aparent BS4 utilizări matchcu expresii regulate, am făcut regex mai larg cu

REF = re.compile(r.*\[(?P<title>.+?)\]\[(?P<identifier>.*?)\].*, re.DOTALL)

Scopul este de a găsi astfel de siruri de caractere și să le înlocuiască cu reale <a>link - uri, dar nu și în cazul în care acestea sunt într - o <code>etichetă (indiferent de adâncimea). Am o cartografiere pentru a obține adresa URL din identifier.

[<code>title<code>][identifier]ar trebui să se potrivească, dar <code>[title][identifier]</code>nu ar trebui.

În cazul în care intrarea este:

<p>[<code>title<code>][identifier]</p>

Ieșirea ar trebui să fie:

<p><a id=identifier href=http://example.com><code>title<code></a></p>

Cu toate acestea, următoarea intrare ar trebui să rămână neatinsă:

<p><code>[title][identifier]</code></p>

Am încercat următoarele:

tags = [tag.parent for tag in soup.find_all(text=REF) if not tag.find_parent(code)]

... dar a fost lipsă tag - uri. Am găsit o explicație în acest post: BeautifulSoup - căutare de text în interiorul unei etichete . Se pare text(sau numele nou string, deși am găsit comportamentul de a fi diferit) , va reveni , Noneatunci când există alte etichete în tag - ul, ceea ce înseamnă că tag - ul <p>[<code>title<code>][identifier]</p>nu va fi compensată.

De asemenea, am crezut că postul a dat soluția:

tags = list(
    soup.find_all(
        lambda tag: tag.name != code and
                    not tag.find_parent(code) and
                    REF.search(tag.text)
    )
)

... dar acum în loc să - mi etichetează aproape de frunze, se returnează tag - uri rădăcină ca <html>și <body>, deoarece tag.textreturnează textul integral, recursiv al tuturor descendenților . Apoi, desigur , aceste etichete conține text de potrivire regex, dar în interiorul <code>tag - uri .

Cea mai bună soluție, cred, ar fi să încercați regex împotriva textului etichetei limitat la o anumită adâncime. Dacă adâncimea-1 text <p>[<code>title</code>][identifier]</p>este [ ][identifier]și profunzime-2 textul din aceeași etichetă este [<code>title</code>][identifier], atunci adâncimea-2 este tot nevoie eu.

Există o modalitate de a face asta? Sau aveți orice altă soluție în minte? M - am gândit că aș putea itera pe toate etichetele de la frunze la rădăcină, lățimea- în primul rând, dar voi avea în continuare aceeași problemă cu tag.textreturnarea textul tuturor descendenților, de asemenea.

Întrebat 19/03/2020 la 22:00
sursa de către utilizator
În alte limbi...                            

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more