1
votes

Séparer les éléments du jeu de résultats BeautifulSoup

Je travaille sur un projet utilisant Python (3.7) et BeautifulSoup (4) dans lequel je dois supprimer certaines données sans connaître la structure exacte du HTML mais en supposant que les informations pertinentes de l'utilisateur seront dans en-têtes, paragraphes, balises pré et code . Après find_all pour ces balises, je souhaite séparer les balises headings et paragraph des balises code et pré de l'objet ResultSet.

Voici ce que J'ai essayé:

required_tags = ["h1", "h2", "h3", "h4", "h5", "pre", "code", "p"]
text_outputs = []
code_outputs = []
pages = [
        "https://bugs.launchpad.net/bugs/1803780",
        "https://bugs.launchpad.net/bugs/1780224",
        "https://docs.openstack.org/keystone/pike/_modules/keystone/assignment/core.html",
        "https://openstack-news.blogspot.com/2018/11/bug-1803780-confusing-circular.html",
        "https://www.suse.com/documentation/suse-openstack-cloud-9/doc-cloud-upstream-user/user"
        "/html/keystone/_modules/keystone/assignment/core.html"
    ]


page = requests.get(pages[0])
    html_text = BeautifulSoup(page.text, 'html.parser')
    text = html_text.find_all(required_tags)
    elements = []
    for e in html_text:
        elements.append(e.parent)
    for t in text:
        for e in elements:
            if e == 'code' or e == 'pre':
                print(e)
                code_outputs.append(t.get_text())
            else:
                text_outputs.append(t.get_text())

Mais cela ne renvoie rien dans code_outputs et text_outputs .

Merci d'avance!


7 commentaires

Quelle URL essayez-vous d'analyser? Veuillez l'ajouter


c'est une liste d'urls, permettez-moi d'ajouter ça!


Oui, ajoutez tout le code pertinent pour réduire les conjectures


Salut @DeveshKumarSingh J'ai ajouté toutes les urls .


pouvez-vous vérifier si l'URL que vous avez a réellement un code et une pré-balise? Je ne pense pas qu'ils ont tous


oui, par exemple, la troisième URL a une balise pre qui comprend un extrait de code.


La ligne if e == 'code' ou e == 'pre': ne vérifie pas si les balises sont égales à code ou pre , il vérifie si l'élément entier est égal à la chaîne code ou à la chaîne pre , ce n'est jamais le cas. et je ne vois pas la nécessité de cette boucle imbriquée pour. pour t dans le texte: pour e dans les éléments: Pourquoi superposez-vous tous les éléments des éléments pour chaque élément du texte?


3 Réponses :


0
votes

Récupérez simplement le nom du parent à partir d'un élément comme

t.parent.name =='code'

Plutôt que de créer une liste d'éléments parents.


2 commentaires

il ne récupère pas les résultats de code et pre , par exemple, si vous voyez l'URL de la troisième page, nous avons une balise pre pour un extrait de code qui devrait être dans le code_outputs mais il n'est pas récupéré.


Vous n'ouvrez que la première page



0
votes

Vous n'obtenez aucune donnée car vous itérez une boucle for interne supplémentaire qui n'est pas requise

json_data = []
for page in pages:
    res = requests.get(page)
    html_text = BeautifulSoup(res.text, 'html.parser')
    text = html_text.find_all(required_tags)
    for t in text:
        if t.name == 'code' or t.name == 'pre':
            code_outputs.append(t.get_text())
        else:
            text_outputs.append(t.get_text())

    data = {page:{"html":text,"code_outputs":code_outputs,"text_outputs":text_outputs}}
    json_data.append(data)

print(json_data)

Voir la condition ci-dessus, vous itérez la balise parent dans la liste des balises enfants pour la boucle et comparez également objet tag avec la chaîne . vous recevez déjà des données de pré-balise dans l'objet de liste text .

for page in pages:
    res = requests.get(page)
    html_text = BeautifulSoup(res.text, 'html.parser')
    text = html_text.find_all(required_tags)   
    for t in text:
        if t.name == 'code' or t.name == 'pre':
            print("===if===")
            code_outputs.append(t.get_text())
        else:
            print("===else===")
            text_outputs.append(t.get_text())

print(code_outputs)
print(text_outputs)

Mise à jour:

 for e in elements:
     if e == 'code' or e == 'pre': 


4 commentaires

Ok, comment puis-je ajouter le lien avec les résultats également, car la sortie finale devrait être une liste contenant le lien, du texte et du code.


C'est ajouter des liens et des informations pertinentes séparément, je dois ajouter le lien, puis c'est du texte ou du code spécifique.


pouvons-nous mettre en forme les extraits de code dans la réponse? ça a l'air très fatigué!


@Abdul Rehman ce que vous voulez, supprimer le texte du site Web ou simplement stocker du HTML filtré



0
votes

vous pouvez essayer ceci:

from bs4 import BeautifulSoup

required_tags = ["h1", "h2", "h3", "h4", "h5", "pre", "code", "p"]
text_outputs = []
code_outputs = []
pages = [
        "https://bugs.launchpad.net/bugs/1803780",
        "https://bugs.launchpad.net/bugs/1780224",
        "https://docs.openstack.org/keystone/pike/_modules/keystone/assignment/core.html",
        "https://openstack-news.blogspot.com/2018/11/bug-1803780-confusing-circular.html",
        "https://www.suse.com/documentation/suse-openstack-cloud-9/doc-cloud-upstream-user/user"
        "/html/keystone/_modules/keystone/assignment/core.html"
    ]


page = requests.get(pages[2], verify=False)


html_text = BeautifulSoup(page.text, 'html.parser')
elements = {}


for tag in required_tags:
    data=list(html_text.find_all(tag))
    data = [dat.text for dat in data]
    if tag == "code" or tag=="pre":
        code_outputs+=data
    else:
        text_outputs+=data


0 commentaires