2012-01-19 26 views
36

Làm cách nào để sử dụng BeautifulSoup, tìm kiếm các thẻ chứa CHỈ thuộc tính mà tôi tìm kiếm? Ví dụ: Tôi muốn tìm tất cả các thẻ <td valign="top">.Cách tìm thẻ chỉ với một số thuộc tính nhất định - BeautifulSoup

Các mã sau đây: raw_card_data = soup.fetch('td', {'valign':re.compile('top')})

được tất cả các dữ liệu tôi muốn, nhưng cũng lấy bất kỳ thẻ <td> có thuộc tính valign:top

Tôi cũng đã cố gắng: raw_card_data = soup.findAll(re.compile('<td valign="top">')) và điều này trả về không có gì (có thể là vì regex xấu)

Tôi đã tự hỏi liệu có cách nào trong BeautifulSoup nói "Tìm các thẻ <td> chỉ có thuộc tính là valign:top "

CẬP NHẬT Ví dụ, nếu một tài liệu HTML chứa <td> thẻ sau đây:

<td valign="top">.....</td><br /> 
<td width="580" valign="top">.......</td><br /> 
<td>.....</td><br /> 

tôi muốn chỉ <td> thẻ đầu tiên (<td width="580" valign="top">) để trở về

Trả lời

49

Như đã giải thích trên BeutifulSoup documentation

Bạn có thể sử dụng này:

soup = BeautifulSoup(html) 
results = soup.findAll("td", {"valign" : "top"}) 

EDIT:

Để trở về thẻ mà chỉ có các valign = "top" thuộc tính, bạn có thể kiểm tra độ dài của thẻ attrs thuộc tính:

from BeautifulSoup import BeautifulSoup 

html = '<td valign="top">.....</td>\ 
     <td width="580" valign="top">.......</td>\ 
     <td>.....</td>' 

soup = BeautifulSoup(html) 
results = soup.findAll("td", {"valign" : "top"}) 

for result in results : 
    if len(result.attrs) == 1 : 
     print result 

Trả lại:

<td valign="top">.....</td> 
+0

Theo nhận xét của tôi về julio.alegria, Điều này sẽ tìm tất cả các thẻ '' với thuộc tính 'valign =" top "', bao gồm các thuộc tính với các thuộc tính khác ('' cũng được trả lại trong tìm kiếm này) đang tìm kiếm một phương thức để tìm các thẻ '' có thuộc tính duy nhất là 'valign =" top "' – Snaxib

+0

Vì vậy, bạn có thể kiểm tra len (tag.attrs). Nếu len (tag.attrs)> 1, bỏ qua thẻ (Tôi đã sửa bài của tôi) –

+0

Tuyệt vời, cảm ơn người đàn ông! – Snaxib

2

Chỉ cần vượt qua nó làm đối số của findAll:

>>> from BeautifulSoup import BeautifulSoup 
>>> soup = BeautifulSoup(""" 
... <html> 
... <head><title>My Title!</title></head> 
... <body><table> 
... <tr><td>First!</td> 
... <td valign="top">Second!</td></tr> 
... </table></body><html> 
... """) 
>>> 
>>> soup.findAll('td') 
[<td>First!</td>, <td valign="top">Second!</td>] 
>>> 
>>> soup.findAll('td', valign='top') 
[<td valign="top">Second!</td>] 
+1

Điều gì xảy ra nếu có các thẻ như vậy: ''? Tôi không muốn lấy chúng, chỉ các thẻ có thuộc tính duy nhất là 'valign =" top "' – Snaxib

26

Bạn có thể sử dụng các chức năng lambda trong findAll như được giải thích trong documentation. Vì vậy mà trong trường hợp của bạn để tìm kiếm td tag với chỉ valign = "top" sử dụng sau đây:

td_tag_list = soup.findAll(
       lambda tag:tag.name == "td" and 
       len(tag.attrs) == 1 and 
       tag["valign"] == "top") 
+3

câu trả lời hay nhất vì nó sử dụng toàn bộ sức mạnh của BS –

+1

Câu trả lời tuyệt vời vì nó mang lại cho bạn kết quả theo cách rất tối ưu. – CrazyGeek

3

Cách dễ nhất để làm điều này là với phong cách CSS mới select phương pháp:

soup = BeautifulSoup(html) 
results = soup.select('td[valign="top"]') 
+0

cũng là phiên làm việc với phiên bản mới nhất. –

4

nếu bạn muốn chỉ tìm kiếm với tên thuộc tính có bất kỳ giá trị nào

from bs4 import BeautifulSoup 
import re 

soup= BeautifulSoup(html.text,'lxml') 
results = soup.findAll("td", {"valign" : re.compile(r".*")}) 
+0

Bạn đang thiếu dấu ngoặc đơn sau 'r '. *" ', Dẫn đến việc này không biên dịch. –

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