2012-12-10 1 views
5

J'utilise Beautiful Soup pour extraire des balises div spécifiques, et il semble que je ne puisse pas utiliser string simple matching.Expression régulière Python pour Belle Soupe

La page a des balises sous forme de

<div class="comment form new"...> 

que je veux ignorer, et aussi quelques balises sous forme de

<div class="comment comment-xxxx..."> 

où les x représentent un nombre entier de longueur arbitraire , et les ellipses représentent un nombre arbitraire d'autres valeurs séparées par des espaces blancs (que je ne suis pas concerné). Je ne peux pas comprendre l'expression regex correcte, d'autant plus que je n'ai jamais utilisé la classe re de python.

En utilisant

soup.find_all(class_="comment") 

trouve tous les tags commençant par le mot commentaire. Je l'ai essayé d'utiliser

soup.find_all(class_=re.compile(r'(comment)()(comment)')) 
soup.find_all(class_=re.compile(r'comment comment.*')) 

et beaucoup d'autres variations, mais je pense que je manque quelque chose évidente ici sur la façon dont le travail des expressions regex ou match(). Quelqu'un peut m'aider?

+1

D'abord, utilisez-vous BS3 ou BS4? On a 'findAll', on a' find_all', ni 'findall' ... – abarnert

+0

Désolé, BS4 - Je n'ai pas pu coller directement à partir de mon code, je vais éditer. – user1890572

+0

Merde, parce que j'avais une réponse pour BS3 ... mais pour BS4, on dirait qu'il n'aime pas les espaces dans les classes peut-être? Ou peut-être que je ne connais pas assez BS4. Je peux correspondre '' comment'', mais pas ''commentaire comment''. Je vais regarder dedans. – abarnert

Répondre

15

Je pense que je l'ai:

>>> [div['class'] for div in soup.find_all('div')] 
[['comment', 'form', 'new'], ['comment', 'comment-xxxx...']] 

Notez que, contrairement à l'équivalent en BS3, c'est pas:

['comment form new', 'comment comment-xxxx...'] 

Et voilà pourquoi votre regexps ne correspondront pas.

Mais vous pouvez faire correspondre, par exemple, ceci:

>>> soup.find_all('div', class_=re.compile('comment-')) 
[<div class="comment comment-xxxx..."></div>] 

Notez que BS ne soit l'équivalent de re.search, non re.match, de sorte que vous n'avez pas besoin 'comment-.*'. Bien sûr, si vous voulez faire correspondre 'comment-12345' mais pas 'comment-of-another-kind vous voudrez, par exemple, 'comment-\d+'.

+0

Je me souviens avoir lu quelque chose à ce sujet dans la documentation de BS4, mais c'est quand même contre-intuitif. Merci beaucoup! Je me suis battu la tête contre ça pendant une heure +. – user1890572

+0

@ user1890572: Je ne sais pas pourquoi, mais je n'ai toujours pas lu les documents BS4 au-delà d'un guide rapide de migration de BS3, donc je me suis habitué à me débrouiller avec des problèmes comme celui-ci code. Pensez-y, si j'étais plus intelligent, je n'aurais pas été capable de répondre. :) – abarnert