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!
3 Réponses :
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.
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
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':
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é
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
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
oupre
, il vérifie si l'élément entier est égal à la chaînecode
ou à la chaînepre
, 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?