1
votes

URL de l'image d'arrière-plan intégrée dans une classe div d'un élément BS4

Je ne suis pas un expert en scraping Web, mais j'ai réussi à obtenir la plupart de mes souhaits. Cependant, j'ai du mal à analyser la dernière partie de mon code, une image d'arrière-plan.

Voici ce que j'ai:

<div class="flex-embed-content flex-embed-cover-image " style="background-image: url('//site.org/photos/0/kp/cr/QOKPCRqjkbbldlo-400x225-noPad.jpg?1528717310')"></div>

Ce qui renvoie: p >

htmlSource.find('div', class_='flex-embed-content flex-embed-cover-image ')

Je suis intéressé par l'URL //site.org/photos/0/kp/cr/QOKPCRqjkbbldlo-400x225-noPad.jpg?1528717310 p>

Comment puis-je l'analyser à partir de htmlSource?

Merci


0 commentaires

5 Réponses :


1
votes

Récupérez l'attribut style et utilisez la manipulation de chaînes. Exemple de méthode ci-dessous (il y en a clairement d'autres)

from bs4 import BeautifulSoup as bs

html = '''<div class="flex-embed-content flex-embed-cover-image " style="background-image: url('//site.org/photos/0/kp/cr/QOKPCRqjkbbldlo-400x225-noPad.jpg?1528717310')"></div>'''

soup = bs(html, 'lxml')

item = soup.select_one('div.flex-embed-content.flex-embed-cover-image')
item['style'].split("url('")[1][:-3]

Remarque J'utilise select_one car il y a une seule correspondance basée sur le html inséré. Vous pouvez utiliser select avec un sélecteur incluant l'attribut style div.flex-embed-content.flex-embed-cover-image [style] et une boucle. Je verrais aussi si vous pouvez réduire le nombre de classes utilisées dans le sélecteur.


2 commentaires

Ce n'est pas idéal, car avec le split vous ne pouvez pas garantir qu'il continue de fonctionner si le site Web modifie ce div en ajoutant un autre élément sur le style, avant l'url. Pour cette raison, regex est généralement idéal pour ces situations: stackoverflow.com/a/54934372/10642035


@LuanNaufal Je suis d'accord. J'en écrirais un mais tu m'as battu! +



0
votes

L'attribut style contient du CSS, ce que beautifulsoup ne sait pas analyser.

Alors, première chose - obtenez le contenu de l'attribut de style. Vous devez maintenant analyser le CSS. Vous pouvez l'analyser vous-même (recherchez url (...) ), ce qui fonctionnera si le site ne change pas beaucoup.

Une autre option consiste à utiliser un analyseur CSS dédié, tel que tinycss . J'utiliserais un analyseur CSS, votre code sera plus résistant aux modifications du site.




1
votes

Tout d'abord, vous devez obtenir votre élément div , et il existe de nombreuses façons de le faire, mais comme vous avez une classe vraiment spécifique, cela suffit (en supposant ici que votre code html est stocké dans le Variable htmlSource :

from bs4 import BeautifulSoup
import re

soup = BeautifulSoup(html, "html.parser")
divElement = soup.select_one('div.flex-embed-content.flex-embed-cover-image')

pattern = r"(?<=url\().*(?='\))"
url = re.search(pattern, divElement["style"]).group(0)

Maintenant, vous devriez prendre l'attribut style , et le filtrer pour l'url, et je suggère d'utiliser regex, et de cette façon, vous n'aurez pas de problème avec les éléments inattendus ajoutés aux heures supplémentaires de style:

pattern = r"(?<=url\().*(?='\))"
url = re.search(pattern, divElement["style"]).group(0) # The group(0) is used to recover the whole match

Le contenu (? dans regex , suppose que notre correspondance commence par ce contenu TEXT_BEFORE, mais ne l'inclut pas dans la correspondance ( assertion lookbegind ), et le (? = TEXT_AFTER) indique le contraire, et ne correspond que si la correspondance suit TEXT_AFTER ( assertion lookahead )

Le code complet serait donc:

soup = BeautifulSoup(htmlSource, "html.parser")
divElement = soup.select_one('div.flex-embed-content.flex-embed-cover-image')


0 commentaires

1
votes

L'une des solutions consiste à utiliser urlextract . Cette classe aide à trouver l'url dans la chaîne.

Code:

site.org/photos/0/kp/cr/QOKPCRqjkbbldlo-400x225-noPad.jpg?1528717310
----
//site.org/photos/0/kp/cr/QOKPCRqjkbbldlo-400x225-noPad.jpg?1528717310

SORTIE:

soup = BeautifulSoup(html,"lxml")
finddiv = htmlSource.find('div', class_='flex-embed-content flex-embed-cover-image')

style = finddiv['style']

for url in extractor.gen_urls(style):

    print (url)
    print('----')
    print('//'+url)


0 commentaires