5
votes

Le site Web à gratter a différents noms de classe

J'essaie de gratter le titre et le prix d'un produit. Je suis confronté à un problème où le site Web a une classe qui varie. Ceci est un exemple,

<a class="K-ab" href="thewebsite.com"><div class="K-l"><div class="K-m">Product Name</div></div><div class="K-k"><div>S$230</div><div>Product Description</div><div>Used</div></div></a>

Quand j'utilise un autre ordinateur, cela montre alors ceci à la place,

<a class="G-ab" href="thewebsite.com"><div class="G-l"><div class="G-m">Product Name</div></div><div class="G-k"><div>S$230</div><div>Product Description</div><div>Used</div></div></a>

J'ai réalisé qu'ils changeaient leurs classes à une lettre aléatoire. J'utilise actuellement BeautifulSoup4 et la bibliothèque de requêtes. Existe-t-il des moyens d'obtenir la classe, autre que l'idée de faire de longues classes "si elif"? Le site Web que j'essaie de gratter est carousell.com J'utilise actuellement un analyseur lxml, si cela peut être utile. Merci pour votre temps.


5 commentaires

1. Sans connaître la structure du html, il est impossible de dire s'il existe d'autres sélecteurs que vous pourriez utiliser à la place des classes. 2. Veuillez lire ici, avant de supprimer des sites Web ( robotstxt.org )


Les seuls qui ne sont pas autorisés sont ceux que mon grattoir ne va pas vraiment


Pouvez-vous partager l'URL du site Web cible?


carousell.com/search/products/…


Comment accédez-vous à ce site avec python?


3 Réponses :


2
votes

BeautifulSoup vous permet d'utiliser une regex comme filtre . Dans votre site, les noms de classe d'une balise une contiennent -ab .

Vous pouvez utiliser

[<a class="G-ab" href="thewebsite.com"><div class="G-l"><div class="G-m">Product Name</div></div><div class="G-k"><div>S$230</div><div>Product Description</div><div>Used</div></div></a>, <a class="K-ab" href="thewebsite.com"><div class="K-l"><div class="K-m">Product Name</div></div><div class="K-k"><div>S$230</div><div>Product Description</div><div>Used</div></div></a>]

Mais dans certains cas, il n'y a pas besoin de termes communs dans les noms de classe, vous pouvez vérifier si vous pouvez essayer d'utiliser des méthodes dans Aller et venir , Aller de côté , En descendant et En remontant les sections de la documentation pour identifier de manière unique l'élément dont vous avez besoin sans vous fier au nom de la classe.

Revenons à votre question

html="""
<a class="G-ab" href="thewebsite.com"><div class="G-l"><div class="G-m">Product Name</div></div><div class="G-k"><div>S$230</div><div>Product Description</div><div>Used</div></div></a>
<a class="K-ab" href="thewebsite.com"><div class="K-l"><div class="K-m">Product Name</div></div><div class="K-k"><div>S$230</div><div>Product Description</div><div>Used</div></div></a>
"""
from bs4 import BeautifulSoup
import re
soup=BeautifulSoup(html,'html.parser')
a_links=soup.find_all('a',class_=re.compile("-ab"))
print(a_links)

Résultats:

soup.find_all('a',class_=re.compile("-ab"))

Les deux balises a avec différents noms de classe contenant -ab ont été sélectionnés.


1 commentaires

Puisqu'il s'agit d'une simple expression régulière, nous pourrions également utiliser le sélecteur CSS contient: 'a [class * = "- ab"]' ou les extrémités avec le sélecteur 'a [class $ = " -ab "] '. Excellente réponse quand même!



1
votes

Oui, ce que @Bitto a mentionné est correct.Vous avez utilisé l'expression régulière pour identifier des éléments uniques.En utilisant re vous pouvez y parvenir.Toutefois, voici votre code.Vous pouvez utiliser pandas Dataframe pour imprimer les résultats.

     Price                                              Title
0     £200                          Acer Aspire Laptop (Used)
1     £700            MSI GP62 LEOPARD i7 12gb Ram windows 10
2     £120                                  Apple MacBook Pro
3     £155                                      iPhone 7 Plus
4     £155                                   Goophone I7 Plus
5     £579  MacBook Air 13.3inch 2014 i7 1.7GHz 8GB Ram 12...
6     £550                          MacBook Pro 2016 16GB Ram
7     £600                    CUSTOM GAMING/MEDIA PC COMPUTER
8     £900     MS I GE62 2QF-419UK APACHE/PRO TRUE FIRE POWER
9     £390           HP Envy 15 Intel Core i7 4000MQ 12GB Ram
10    £188                                   Goophone I7 Plus
11    £650                 Apple IMac 27" i7 2.8Ghz Quad Core
12    £600             Custom Gaming Pc (Excellent Condition)
13    £499               iMac 21.5inch with wireless keyboard
14  £1,299             MacBook Pro Retina 13 Inches AppleCare
15    £700                              I7 4790k Water Cooled
16    £650                                     Gigabyte P15V2
17    £280                                 Two Monitors i7 PC
18    £250                                  Gaming laptop pro
19  £1,000                              MAC BOOK PRO 15 Ritna
20    £550  Apple MacBook Pro Laptop - A1286 15.2" 500 GB ...

Sortie:

from bs4 import BeautifulSoup
import requests
import re
import pandas as pd

html=requests.get("https://carousell.com/search/products/?cc_id=2195&query=I7&sort_by=time_created%2Cdescending")
soup=BeautifulSoup(html.text,"html.parser")
atag=soup.find_all('a', class_=re.compile("-ab"))
itemtitle=[]
itemprice=[]
for a in atag:
  for title,price in zip(a.find_all('div', class_=re.compile("-m")),a.find_all('div', class_=re.compile("-k"))):
      itemtitle.append(title.text)
      itemprice.append(price.find('div').text)

df=pd.DataFrame({"Title" :itemtitle, "Price" : itemprice})
print(df)


0 commentaires

1
votes

Vous pouvez utiliser le sélecteur attribut = valeur dont les extrémités sont $ operator

items = soup.select("a[class$='-ab']")


1 commentaires

oh je c qu'il a été ajouté en commentaire ailleurs