Convertir du HTML en texte brut, comment empêcher deux paragraphes de texte de coller ensemble

Cet article vise le problème de l'adhésion du texte lors de la conversion de HTML en texte brut et explique en détail l'utilisation combinée des paramètres separator et strip de get_text dans Beautiful Soup. Fournit des cas de test DOM synthétiques et des codes d'assertion Python complets, y compris les limites au niveau des blocs/en ligne, le traitement des espaces, des méthodes de préparation d'entrée claires et des critères d'acceptation, et fournit des entrées supplémentaires à OmniDoc dans des scénarios de documents complexes.

Lors de la conversion de HTML en texte brut, deux paragraphes de texte restent collés, principalement parce que get_text() est appelé directement sans spécifier de stratégie de séparation. Beautiful Soup assemble tous les nœuds de texte de manière transparente par défaut et les limites entre les éléments au niveau du bloc disparaissent. Ce problème est courant lors de l’utilisation de Beautiful Soup pour extraire du contenu Web.

Au lieu d'utiliser des expressions régulières pour deviner où casser après l'extraction, vous pouvez combiner correctement les paramètres separator et strip pendant l'extraction. Cet article utilise des exemples synthétiques pour démontrer cette méthode, donne un code d'assertion exécutable et explique quelles situations nécessitent une révision manuelle.

Après avoir lu cet article, vous pouvez déterminer si vos résultats d'extraction sont bloqués, utiliser des scripts d'assertion pour vérifier le résultat et clarifier quels problèmes peuvent être résolus par des paramètres et lesquels doivent être modifiés.

Que dois-je faire si je convertis du HTML en texte brut ? Conclusion en une phrase

Utilisez d'abord la combinaison de separator='\n' et strip=True pour appeler get_text(), puis gérez les balises non pertinentes et les problèmes structurels en fonction de la situation de la page.

votre situationPratiques recommandéesraison
Le texte entre les paragraphes ou les éléments de la liste reste colléDéfinissez à la fois separator='\n' et strip=Truele séparateur est responsable de la séparation, la bande supprime les blancs de début et de fin
Seul le séparateur est définiPlus strip=TrueSinon, les espaces en retrait sans signification seront conservés
Seule la bande est définieAjoutez également un séparateurLes lignes peuvent encore coller les unes aux autres
La page contient des balises non pertinentes telles que scriptSupprimez ces balises avant d'appelerLes paramètres de get_text ne résolvent que le format, pas le nettoyage du contenu.
Contient un DOM de table, de canevas ou d'ombreModifier la procédure de collecte ou accepter les informations manquantesCe type de contenu ne peut pas être résolu en ajustant les paramètres

Pièges et sémantique des paramètres du comportement par défaut

Pourquoi ça colle ?

La méthode get_text() accepte deux paramètres clés : separator et strip. Si aucun paramètre n'est transmis, il connectera directement tous les nœuds de texte dans l'arborescence des balises.

Ce comportement par défaut est très problématique pour les éléments de niveau bloc tels que div, p et li. Les sauts de ligne et les retraits dans le code source HTML sont souvent transformés en chaînes vides ou ignorés après l'analyse, et les frontières sémantiques disparaissent.

À quoi servent le séparateur et la bande ?

  • séparateur : Définit l'insertion entre les nœuds de texte. Le réglage sur '\n' est une pratique courante, mais pas parfaite. Si le HTML est profondément imbriqué, le retour à la ligne global peut entraîner un grand nombre de lignes vides.
  • strip : contrôlez s'il faut supprimer l'espace vide au début et à la fin de chaque fragment de texte. Lorsque strip=True, Beautiful Soup exécutera d'abord .strip() sur chaque NavigableString indépendante, puis utilisera un séparateur pour les séparer.

Par exemple, <p> Hello </p> obtiendra un Hello propre au lieu de \n Hello \n avec une sortie de données modifiées.

Les deux doivent être utilisés ensemble :

  • Utiliser uniquement un séparateur sans bande conservera les espaces en retrait dénués de sens.
  • Avec seulement une bande et sans séparateur, une seule ligne sera propre, mais il peut toujours y avoir une adhérence entre les lignes.

Pour plus de descriptions de paramètres, veuillez vous référer à Documentation officielle de Beautiful Soup : get_text().

Cas de test des limites du DOM synthétique

Pour valider la logique d'extraction, des échantillons HTML synthétiques contenant des problèmes de limites typiques doivent être construits au lieu de s'appuyer sur de vraies pages Web instables. Les cas de test suivants couvrent trois situations : l'adhésion d'éléments au niveau du bloc, l'espacement des éléments en ligne et l'espace blanc excessif.

Échantillon d'entrée (exemple synthétique) :

<div>
    <p>第一段文字</p>
    <p>第二段文字<span>内联补充</span></p>
    <ul>
        <li> 列表项A </li>
        <li>列表项B</li>
    </ul>
</div>

Sortie correcte attendue :

第一段文字

第二段文字
内联补充

列表项A
列表项B

Il convient de noter que separator='\n' agit sur les nœuds de texte extraits et ne générera pas automatiquement des sauts de ligne doubles basés sur des balises au niveau du bloc. Il doit y avoir des sauts de ligne clairs entre les paragraphes et les éléments de la liste, et les espaces supplémentaires avant et après les éléments de la liste doivent être supprimés. "Deuxième texte" et "Supplément en ligne" sont situés dans des étiquettes différentes et sont des nœuds de texte, ils seront donc séparés par des délimiteurs.

Erreurs et saisie des limites

Si l'entrée devient <p>End</p><script>alert(1)</script><p>Start</p> et que la balise de script n'est pas filtrée, la sortie contiendra alert(1). Cela est vrai même si le séparateur est défini. L'inclusion ou non des nœuds de script dans le texte dépend de l'analyseur et du type de nœud.

La bonne façon de gérer cela consiste à utiliser soup.find_all('script') pour supprimer les balises non pertinentes avant d'appeler get_text, ou pour ignorer des types de balises spécifiques lors du parcours. Les paramètres de get_text résolvent uniquement le problème de format, pas le problème de nettoyage du contenu.

Implémentation Python et vérification des assertions

Le code ci-dessous crée l'exemple ci-dessus en mémoire et effectue une vérification déterministe. L'exemple dépend de beautifulsoup4 et la version 4.9.0 et supérieure est recommandée.

Pour tester des fichiers externes, veuillez d'abord enregistrer le HTML au format UTF-8, puis utiliser open('file.html', encoding='utf-8') pour le lire afin d'éviter des erreurs d'encodage provoquant des exceptions d'analyse. Le code ne contient aucune requête réseau et est complètement autonome.

from bs4 import BeautifulSoup

# 合成示例:模拟常见的HTML文本边界问题
html_content = """
<div>
    <p>第一段文字</p>
    <p>第二段文字<span>内联补充</span></p>
    <ul>
        <li> 列表项A </li>
        <li>列表项B</li>
    </ul>
</div>
"""

soup = BeautifulSoup(html_content, 'html.parser')

# 关键配置:separator定义边界,strip清理碎片空白
text_result = soup.get_text(separator='\n', strip=True)

# 过滤空行以获得干净的语义行
lines = [line for line in text_result.split('\n') if line]

# 验收断言:确保边界清晰且无脏数据
assert lines[0] == '第一段文字', f"段落粘连或内容错误: {lines[0]}"
assert lines[1] == '第二段文字', "块级元素间未正确分隔"
assert lines[2] == '内联补充', "内联元素文本节点被错误合并"
assert lines[3] == '列表项A', f"列表项前置空格未清除: '{lines[3]}'"
assert lines[4] == '列表项B', "列表项间边界丢失"

print("提取结果预览:")
for i, line in enumerate(lines):
    print(f"{i}: [{line}]")

Le résultat attendu de ce code est cinq lignes de texte clair. Si votre environnement génère plus de lignes vides, cela signifie qu'il existe des nœuds NavigableString vierges dans le DOM qui n'ont pas été supprimés. Il s'agit d'un comportement normal de html.parser et peut être filtré avec des compréhensions de liste après la division.

Ce code sert uniquement à démontrer le principe de combinaison de paramètres et ne doit pas être utilisé directement sur des pages complexes dans l'environnement de production.

📊 Comparaison de base

planEffetlimites
Utilisez uniquement separator='\n'Il y a des sauts de ligne entre les blocsGardez les espaces en retrait, un grand nombre de lignes vides peuvent apparaître lorsque l'imbrication est profonde
Utilisez uniquement strip=TrueNettoyer le début et la fin de chaque paragrapheLes lignes peuvent encore coller les unes aux autres
Utilisez les deux en même tempsPrise en compte à la fois de la séparation et de la suppression des espacesLes balises non pertinentes doivent toujours être supprimées avant l'extraction
Utilisez des expressions régulières pour deviner la nouvelle ligne après l'extractionApparemment flexibleNon recommandé, la priorité doit être donnée à la combinaison correcte des paramètres lors de l'extraction

Critères d'acceptation et limites de révision manuelle

L'extraction automatisée ne peut pas permettre une restauration visuelle à 100 %. Le tableau suivant indique comment faire la distinction entre les situations « code réparable » et « nécessite une intervention humaine ». Le jugement est basé sur la structure du DOM et non sur un sentiment subjectif.

observerce qu'il faut faireil ne faut pas en déduire
Séparation des nœuds en ligneVérifiez si la phrase est diviséeLe délimiteur agit sur les nœuds de texte
Aplatissement du tableauConserver la structure des lignes et des colonnes pour un traitement séparéVous ne pouvez pas uniquement compter sur get_text
Dessiner du contenu dynamiquementIdentifier les lacunes de collecteL'analyse statique n'est pas égale au rendu du navigateur

Portée explicite d'inapplicabilité : Beautiful Soup ne peut pas obtenir d'informations valides lorsque le code HTML contient une grande quantité de texte généré par des pseudo-éléments CSS, du contenu rendu par Canvas ou Shadow DOM. À ce stade, le débogage des paramètres ne doit pas continuer, mais le schéma d'acquisition doit être modifié ou les informations manquantes doivent être acceptées.

🎯 Quelle méthode vous convient ?

si tu……

Besoin d'extraire le texte brut des paragraphes et des éléments de liste

Définissez separator='\n' et strip=True et vérifiez la sortie avec un script d'assertion.

Il y a de nombreuses balises de script ou de style dans la page

Supprimez ces balises avant d'appeler get_text et ne vous attendez pas à ce que les paramètres résolvent les problèmes de contenu.

Nécessité de conserver la structure des lignes et des colonnes du tableau

Ne comptez pas uniquement sur get_text, gérez la structure de la table séparément.

La page repose sur le rendu du navigateur ou Shadow DOM

Modifiez le plan de collecte ou enregistrez clairement les écarts de collecte lors de la réception.

❓ Questions fréquemment posées (FAQ)

1. Est-il suffisant de simplement définir un séparateur ?

pas assez. Définir uniquement un séparateur préservera les espaces d'indentation dénués de sens, et strip=True devra également être ajouté.

2. Pourquoi y a-t-il des lignes vides dans la sortie ?

Il peut y avoir des nœuds NavigableString vides dans le DOM qui n'ont pas été supprimés. Il s'agit d'un comportement normal de html.parser et peut être filtré avec des compréhensions de liste après la division.

3. Pourquoi la balise script apparaît-elle dans les résultats ?

Les paramètres de get_text résolvent uniquement le problème de format. Doit être supprimé avec soup.find_all('script') avant l'appel, ou ignoré pendant le parcours.

4. Comment vérifier si le résultat de l'extraction est correct ?

Construisez un ensemble de tests synthétiques de 5 à 10 cas extrêmes typiques et exécutez des scripts d'assertion. Si le taux de réussite est inférieur aux attentes, vérifiez si vous devez prétraiter le DOM avant de l'extraire.

📝Résumé

Le cœur du problème d’adhésion réside dans la combinaison des paramètres lors de l’extraction, et non dans la réparation des cordes après l’extraction. Parcourez d’abord les échantillons et les assertions synthétiques, puis traitez les balises non pertinentes et les problèmes structurels dans la page réelle.

Essayez-le maintenant : téléchargez le document pour lancer la traduction, en conservant la mise en page d'origine.

Mis à jour le 2026-11-14