2012-10-18 34 views
8

Tôi đang thực hiện một số thao tác dọn dẹp HTML với BeautifulSoup. Noob cho cả Python & BeautifulSoup. Tôi đã xóa thẻ chính xác như sau, dựa trên câu trả lời tôi tìm thấy ở nơi khác trên Stackoverflow:Xóa tất cả các kiểu nội tuyến bằng cách sử dụng BeautifulSoup

[s.extract() for s in soup('script')] 

Nhưng cách xóa kiểu nội tuyến? Ví dụ như sau:

<p class="author" id="author_id" name="author_name" style="color:red;">Text</p> 
<img class="some_image" href="somewhere.com"> 

Sẽ trở thành:

<p>Text</p> 
<img href="somewhere.com"> 

Làm thế nào để xóa các lớp nội tuyến, id, các thuộc tính tên & phong cách của tất cả các yếu tố?

Câu trả lời cho các câu hỏi tương tự khác Tôi có thể tìm tất cả được đề cập bằng cách sử dụng trình phân tích cú pháp CSS để xử lý, thay vì BeautifulSoup, nhưng vì nhiệm vụ chỉ đơn giản là xóa thay vì thao tác các thuộc tính và là quy tắc chăn cho tất cả các thẻ, tôi đã hy vọng tìm được cách để làm tất cả trong BeautifulSoup.

Trả lời

25

Bạn không cần phải phân tích cú pháp bất kỳ CSS nào nếu bạn chỉ muốn xóa tất cả. BeautifulSoup cung cấp một cách để loại bỏ toàn bộ các thuộc tính như vậy:

for tag in soup(): 
    for attribute in ["class", "id", "name", "style"]: 
     del tag[attribute] 

Ngoài ra, nếu bạn chỉ muốn xóa toàn bộ các thẻ (và các nội dung của họ), bạn không cần phải extract(), mà trả về thẻ. Bạn chỉ cần decompose():

[tag.decompose() for tag in soup("script")] 

Không khác biệt lớn, nhưng chỉ là một thứ khác mà tôi đã tìm thấy khi xem tài liệu. Bạn có thể tìm thêm chi tiết về API trong BeautifulSoup documentation, với nhiều ví dụ.

+0

Tôi đã sử dụng trích xuất() trong trường hợp tôi quyết định tạo danh sách mã đã xóa bất kỳ lúc nào, nhưng phân tách() cũng hoạt động tốt để loại bỏ hoàn toàn và hủy thẻ & nội dung. Cảm ơn vì đoạn mã thuộc tính-xóa, hoạt động như một nét duyên dáng! – Ila

+0

Làm cho tinh thần. Tôi sẽ để lại ghi chú về 'decompose()' cho bất kỳ ai khác có thể vấp ngã điều này. – jmk

7

Tôi sẽ không làm điều này trong BeautifulSoup - bạn sẽ dành nhiều thời gian để thử, thử nghiệm và làm việc xung quanh các trường hợp cạnh.

Bleach thực hiện chính xác điều này cho bạn. http://pypi.python.org/pypi/bleach

Nếu bạn làm điều này trong BeautifulSoup, tôi khuyên bạn nên sử dụng phương pháp "danh sách trắng", như Bleach. Quyết định thẻ nào có thể có thuộc tính nào và loại bỏ mọi thẻ/thuộc tính không khớp.

+0

Tuyệt, tôi không biết gì về Bleach.Tôi đã không nghĩ đến trường hợp sử dụng, nhưng nếu mục tiêu là để khử trùng HTML không tin cậy, thì điều này chắc chắn có vẻ như là một cách tiếp cận tốt hơn. Bạn nhận được upvote của tôi! – jmk

+0

Bleach khá tuyệt. Tôi thực sự thích nó. –

1

Dựa trên chức năng JMK của, tôi sử dụng chức năng này để loại bỏ cơ sở thuộc tính trên một danh sách trắng:

Làm việc trong python2, BeautifulSoup3

def clean(tag,whitelist=[]): 
    tag.attrs = None 
    for e in tag.findAll(True): 
     for attribute in e.attrs: 
      if attribute[0] not in whitelist: 
       del e[attribute[0]] 
     #e.attrs = None  #delte all attributes 
    return tag 

#example to keep only title and href 
clean(soup,["title","href"]) 
+0

Bạn không nên truyền các cấu trúc có thể thay đổi được như các giá trị tham số hàm mặc định. Như đã thấy [ở đây] (http://effbot.org/zone/default-values.htm). –

0

Đây là giải pháp của tôi cho Python3 và BeautifulSoup4:

def remove_attrs(soup, whitelist=tuple()): 
    for tag in soup.findAll(True): 
     for attr in [attr for attr in tag.attrs if attr not in whitelist]: 
      del tag[attr] 
    return soup 

Nó hỗ trợ danh sách trắng các thuộc tính cần được lưu giữ. :) Nếu không có danh sách trắng nào được cung cấp, tất cả các thuộc tính sẽ bị xóa.

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