Obtenir uniquement des nombres de BeautifulSoup au lieu de la div entière

Nov 24 2020

J'essaie d'apprendre le python en créant un petit programme de websraping pour me faciliter la vie, bien que je rencontre des problèmes avec uniquement le nombre lors de l'utilisation de BS4. J'ai pu obtenir le prix en récupérant une annonce réelle, mais j'aimerais obtenir tous les prix sur la page.

Voici mon code:

from bs4 import BeautifulSoup
import requests
prices = []
url = 'https://www.kijiji.ca/b-cars-trucks/calgary/new__used/c174l1700199a49?ll=51.044733%2C-114.071883&address=Calgary%2C+AB&radius=50.0'
result = requests.get(url)
print (result.status_code)
src = result.content
soup = BeautifulSoup(src, 'html.parser')
print ("CLEARING")
price = soup.findAll("div", class_="price")
prices.append(price)
print (prices)

Voici ma sortie

[<div class="price">
                        
                            
                            
                                
                                
                                    $46,999.00 <div class="dealer-logo"> <div class="dealer-logo-image"> <img src="https://i.ebayimg.com/00/s/NjBYMTIw/z/xMQAAOSwi9ZfoW7r/$_69.PNG"/>
</div>
</div>
</div>

Idéalement, je voudrais seulement que la sortie soit "46 999,00".

J'ai essayé avec text = True, bien que cela ne fonctionne pas et que je n'obtiendrais aucun résultat à part une liste vide.

Je vous remercie

Réponses

1 MendelG Nov 24 2020 at 22:54

Une option sans utiliser RegEx consiste à filtrer les balises qui indiquent startwith()un signe dollar $:

import requests
from bs4 import BeautifulSoup

URL = 'https://www.kijiji.ca/b-cars-trucks/calgary/new__used/c174l1700199a49?ll=51.044733%2C-114.071883&address=Calgary%2C+AB&radius=50.0'

soup = BeautifulSoup(requests.get(URL).content, "html.parser")

price_tags = soup.find_all("div", class_="price")

prices = [
    tag.get_text(strip=True)[1:] for tag in price_tags
    if tag.get_text(strip=True).startswith('$')
]

print(prices)

Production:

['48,888.00', '21,999.00', '44,488.00', '5,500.00', '33,000.00', '14,900.00', '1,750.00', '35,600.00', '1,800.00', '25,888.00', '36,888.00', '32,888.00', '30,888.00', '18,888.00', '21,888.00', '29,888.00', '22,888.00', '30,888.00', '17,888.00', '17,888.00', '16,888.00', '22,888.00', '22,888.00', '34,888.00', '31,888.00', '32,888.00', '30,888.00', '21,888.00', '15,888.00', '21,888.00', '28,888.00', '19,888.00', '18,888.00', '30,995.00', '30,995.00', '30,995.00', '19,888.00', '47,995.00', '21,888.00', '46,995.00', '32,888.00', '29,888.00', '26,888.00', '21,888.00']
3 ATIFADIB Nov 24 2020 at 13:14

Vous devez obtenir la partie texte de la balise, puis effectuer un traitement regex dessus.

import re

def get_price_from_div(div_item):
    str_price = re.sub('[^0-9\.]','', div_item.text)
    float_price = float(str_price)
    return float_price

Appelez simplement cette méthode dans votre code après avoir trouvé les divs

from bs4 import BeautifulSoup
import requests
prices = []
url = 'https://www.kijiji.ca/b-cars-trucks/calgary/new__used/c174l1700199a49?ll=51.044733%2C-114.071883&address=Calgary%2C+AB&radius=50.0'
result = requests.get(url)
print (result.status_code)
src = result.content
soup = BeautifulSoup(src, 'html.parser')
print ("CLEARING")
price = soup.findAll("div", class_="price")
prices.extend([get_price_from_div(curr_div) for curr_div in price])
print (prices)