2012-11-09 3 views
1

저는 기사에서 내용을 추출하고 불필요한 것들을 제거하는 스크립트를 작성하고 있습니다. 스크립트 및 스타일. 여기에 트림 기능의 코드 (요소는 웹 페이지의 내용을 포함하는 HTML 요소)의아름다운 스프 오류 : '<class'bs4.element.Tag '>'객체에 'content'속성이 없습니다?

'<class 'bs4.element.Tag'>' object has no attribute 'contents' 

: 아름다운 수프는 다음과 같은 예외를 발생 유지

def trim(element): 
    elements_to_remove = ('script', 'style', 'link', 'form', 'object', 'iframe') 
    for i in elements_to_remove: 
     remove_all_elements(element, i) 

    attributes_to_remove = ('class', 'id', 'style') 
    for i in attributes_to_remove: 
     remove_all_attributes(element, i) 

    remove_all_comments(element) 

    # Remove divs that have more non-p elements than p elements 
    for div in element.find_all('div'): 
     p = len(div.find_all('p')) 
     img = len(div.find_all('img')) 
     li = len(div.find_all('li')) 
     a = len(div.find_all('a')) 

     if p == 0 or img > p or li > p or a > p: 
      div.decompose() 

는 스택 추적을 보면,

# Remove divs that have more non-p elements than p elements 
    for div in element.find_all('div'): 
     p = len(div.find_all('p')) # <-- div.find_all('p') 

bs4.element.Tag의 인스턴스 속성 '내용'이없는 내가 왜하지 않습니다 문제는 바로 문에 대한을 한 후에이 방법에서 오는 것 같다?

Environment: 


Request Method: POST 
Request URL: http://localhost:8000/read/add/ 

Django Version: 1.4.1 
Python Version: 2.7.3 
Installed Applications: 
('django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.sites', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'home', 
'account', 
'read', 
'review') 
Installed Middleware: 
('django.middleware.common.CommonMiddleware', 
'django.contrib.sessions.middleware.SessionMiddleware', 
'django.middleware.csrf.CsrfViewMiddleware', 
'django.contrib.auth.middleware.AuthenticationMiddleware', 
'django.contrib.messages.middleware.MessageMiddleware') 


Traceback: 
File "/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response 
    111.       response = callback(request, *callback_args, **callback_kwargs) 
File "/home/marco/sandra/read/views.py" in add 
    24.    Article.objects.create_article(request.user, url) 
File "/home/marco/sandra/read/models.py" in create_article 
    11.   title, content = logic.process_html(web_page.read()) 
File "/home/marco/sandra/read/logic.py" in process_html 
    7.  soup = htmlbarber.give_haircut(BeautifulSoup(html_code, 'html5lib')) 
File "/home/marco/sandra/read/htmlbarber/__init__.py" in give_haircut 
    45.  scissor.trim(element) 
File "/home/marco/sandra/read/htmlbarber/scissor.py" in trim 
    35.   p = len(div.find_all('p')) 
File "/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py" in find_all 
    1128.   return self._find_all(name, attrs, text, limit, generator, **kwargs) 
File "/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py" in _find_all 
    413.     return [element for element in generator 
File "/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py" in descendants 
    1140.   if not len(self.contents): 
File "/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py" in __getattr__ 
    924.    "'%s' object has no attribute '%s'" % (self.__class__, tag)) 

Exception Type: AttributeError at /read/add/ 
Exception Value: '<class 'bs4.element.Tag'>' object has no attribute 'contents' 

은 다음과 같습니다 여기

는 역 추적 (이것은 내가 일하고 있어요 장고 프로젝트의 일부)의 ... 나는 실제 웹 페이지에 그것을 밖으로 시도하고 요소가 P의와 IMG의 가득했습니다 remove_all_ * 함수의 소스 코드 :

def remove_all_elements(element_to_clean, unwanted_element_name): 
    for to_remove in element_to_clean.find_all(unwanted_element_name): 
     to_remove.decompose() 

def remove_all_attributes(element_to_clean, unwanted_attribute_name): 
    for to_inspect in [element_to_clean] + element_to_clean.find_all(): 
     try: 
      del to_inspect[unwanted_attribute_name] 
     except KeyError: 
      pass 

def remove_all_comments(element_to_clean): 
    for comment in element_to_clean.find_all(text=lambda text:isinstance(text, Comment)): 
     comment.extract() 
+0

그건 이상합니다. 전체 추적을 게시하면 도움이됩니다. – Iguananaut

+0

for 루프에서 모든 remove_all_elements 호출을 합산 할 수 있습니다. 현재 문제는 해결되지 않지만 코드의 가독성이 향상됩니다. – iTayb

+0

@iTayb 팁 주셔서 고마워요. –

답변

1

내가 생각하는 문제는 remove_all_elements 또는 다른 곳에서 코드에서 당신이 태그의 일부 contents 속성을 삭제하는 것입니다.

to_remove.decompose()으로 전화하면 이런 현상이 발생합니다.

다음
def decompose(self): 
    """Recursively destroys the contents of this tree.""" 
    self.extract() 
    i = self 
    while i is not None: 
     next = i.next_element 
     i.__dict__.clear() 
     i = next 

가 수동으로이 함수를 호출 할 경우 발생하는 것입니다 : : 여기에 그 방법에 대한 소스입니다

>> soup = BeautifulSoup('<div><p>hi</p></div>') 
>>> d0 = soup.find_all('div')[0] 
>>> d0 
<div><p>hi</p></div> 
>>> d0.decompose() 
>>> d0 
Traceback (most recent call last): 
... 
Traceback (most recent call last): 
AttributeError: '<class 'bs4.element.Tag'>' object has no attribute 'contents' 

그것은 당신이 태그에 decompose이라고 일단 당신이 사용하려고 시도해서는 안 나타납니다 그 태그. 나는 이것이 어디에서 일어나고 있는지 확실히 모른다. 나는 검사를 시도 할 것

것은 당신의 trim() 기능에 항상 len(element.__dict__) > 0 그.

+0

잘 모르겠습니다. del 문을 사용하는 유일한 곳은 del_inspect [unwanted_attribute_name]입니다. –

+0

모든 remove_all_ * 함수를 주석 처리했지만 여전히 작동하지 않습니다. 나는 모든 것을 주석 처리하고 p = len (div.find_all ('p'))을 p = 99로 대체하고 놀랍게도 충분히 예외를 발생시키지 않았습니다! : OI 그 이상한 찾으십시오 ... –

+0

내가 div.dextom()와 div.extract()로 대체하고 그게 효과가 : div는 for 문에 element.find_all의 현재 요소의 별칭으로 정의되어있을 수 있습니다 'div') 그리고 'decomposing'div가 이러한 이슈로 연결 되는가? –

관련 문제