2009-08-07 36 views
37

nếu một trang có <div class="class1"><p class="class1">, thì soup.findAll(True, 'class1') sẽ tìm thấy cả hai.Súp đẹp không thể tìm thấy lớp CSS nếu đối tượng có các lớp khác, quá

Nếu nó có <p class="class1 class2">, tuy nhiên, nó sẽ không được tìm thấy. Làm thế nào để tôi tìm thấy tất cả các đối tượng với một lớp nhất định, bất kể họ có các lớp khác không?

+3

** Update **: Đây được cho là đã được cố định trong 4 beta 5: https://bugs.launchpad.net/beautifulsoup/+bug/410304 – endolith

Trả lời

15

Chỉ trong trường hợp ai đó gặp phải câu hỏi này. BeautifulSoup hiện hỗ trợ điều này:

Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] 
Type "copyright", "credits" or "license" for more information. 

In [1]: import bs4 

In [2]: soup = bs4.BeautifulSoup('<div class="foo bar"></div>') 

In [3]: soup(attrs={'class': 'bar'}) 
Out[3]: [<div class="foo bar"></div>] 

Ngoài ra, bạn không phải nhập findAll nữa.

34

Thật không may, BeautifulSoup coi đây là lớp học có không gian trong đó 'class1 class2' thay vì hai lớp ['class1','class2']. Cách giải quyết là sử dụng cụm từ thông dụng để tìm kiếm lớp thay vì chuỗi.

này hoạt động:

soup.findAll(True, {'class': re.compile(r'\bclass1\b')}) 
+2

https://bugs.launchpad.net/bugs/410304 – endolith

+3

Điều này dường như đã được khắc phục ngay bây giờ. – Kugel

+1

@Kugel: thêm một câu trả lời khác sau đó? – endolith

10

Bạn nên sử dụng lxml. Nó hoạt động với nhiều giá trị lớp được phân tách bằng dấu cách ('class1 class2').

Mặc dù tên của nó, lxml cũng là để phân tích cú pháp và cào HTML. Nó nhanh hơn rất nhiều so với BeautifulSoup và thậm chí còn xử lý HTML "bị hỏng" tốt hơn so với BeautifulSoup (yêu cầu của họ đối với danh tiếng). Nó cũng có API tương thích cho BeautifulSoup nếu bạn không muốn tìm hiểu API lxml.

Ian Bicking agrees và thích lxml trên BeautifulSoup.

Không có lý do gì để sử dụng BeautifulSoup nữa, trừ khi bạn đang sử dụng Google App Engine hoặc thứ gì đó không hoàn toàn là Python không được phép.

Bạn thậm chí có thể sử dụng bộ chọn CSS với lxml, vì vậy việc sử dụng dễ dàng hơn rất nhiều so với BeautifulSoup. Thử chơi với nó trong bảng điều khiển Python tương tác.

+7

Từ tài liệu của lxml: "Trong khi libxml2 (và do đó lxml) cũng có thể phân tích cú pháp HTML bị hỏng, BeautifulSoup tỏ ra khoan dung hơn một chút và có hỗ trợ siêu dữ liệu để phát hiện mã hóa". – endolith

+0

Tôi đã thử nó và nó thực sự là đẹp hơn cho loại điều này. – endolith

+0

Vui vì bạn thích nó. Hy vọng bạn sẽ lan truyền từ quá, lxml là một thư viện được đánh giá cao. Tôi nghĩ nhiều người bỏ qua nó vì nó có 'XML' trong tên và tài liệu của nó không đẹp như BeautifulSoup. BS có một sự quyến rũ với nó với tên và đồ họa, khiến nó hấp dẫn hơn một chút vì những lý do hời hợt. – aehlke

2

Rất hữu ích khi tìm kiếm thẻ có một lớp CSS nhất định, nhưng tên của thuộc tính CSS, "lớp", là một từ dành riêng trong Python. Sử dụng lớp làm đối số từ khóa sẽ cho bạn lỗi cú pháp. Tính đến Beautiful Soup 4.1.2, bạn có thể tìm kiếm theo lớp CSS sử dụng lập luận class_ keyword:

Giống như:

soup.find_all("a", class_="class1") 
+0

Xin lỗi, nhưng tôi tin rằng câu trả lời của bạn là sai. Theo tài liệu của Beautiful Soup (http://www.crummy.com/software/BeautifulSoup/bs3/documentation.html#Searching%20by%20CSS%20class), có hai tùy chọn để sử dụng 'find_all' để tìm thẻ có Lớp CSS: chuyển tên lớp như là một String hoặc tạo ra một dict với khóa "class" và một giá trị với tên của lớp CSS. –

+0

Vui khi bạn xem câu trả lời của tôi, nhưng tôi đang sử dụng bs4, không bs3, có thể giao diện đã thay đổi @ RodrigoTaboada –

+0

Theo tài liệu Soup4 đẹp [link] (http://www.crummy.com/software/BeautifulSoup/bs4/ doc/# search-by-css-class) –

Các vấn đề liên quan