2012-09-16 5 views
2

나는 BeautifulSoup을 사용하여 여러 XML 문서 피드를 파싱 중이며 비표준 CDATA 태그를 사용자 정의 XML 태그로 대체하기 위해 사전 처리 작업을 수행하려고합니다. 설명하기 :CDATA NavigableString을 BeautifulSoup의 태그로 바꾸기

다음 XML 소스 ...

<title>The end of the world as we know it</title> 
<category><![CDATA[Planking Dancing]]></category> 
<pubDate><![CDATA[Sun, 16 Sep 2012 12:00:00 EDT]]></pubDate> 
<dc:creator><![CDATA[Bart Simpson]]></dc:creator> 

...로 변신 것 :이 질문은 SO 이전에 요청 된 생각하지 않는다

<title>The end of the world as we know it</title> 
<category><myTag>Planking Dancing<myTag></category> 
<pubDate><myTag>Sun, 16 Sep 2012 12:00:00 EDT<myTag></pubDate> 
<dc:creator><myTag>Bart Simpson<myTag></dc:creator> 

(I 몇 가지 다른 SO 쿼리를 시도). 나는 또한 .findAll('cdata', text=True)을 사용하여 몇 가지 다른 접근법을 시도하고 각각의 결과에 BeautifulSoup replaceWith() 메서드를 적용하여 NavigableString을 적용했습니다. 내가 시도한 시도는 대체가 없거나 재귀 루프처럼 보입니다.

이전 시도를 게시하게되어 기쁩니다. 그러나 여기에서의 문제는 매우 간단합니다. 누군가가 BeautifulSoup 3을 사용하여 위의 검색 및 교체를 수행하는 방법에 대한 명확한 예를 게시 할 수 있기를 바랍니다.

답변

2

CDataNavigableString의 서브 클래스이기 때문에 먼저 각 CData의 인스턴스인지 여부를 을 테스트하는 모든 NavigableString 개체에 대한 검색 및 모든 CData 요소를 찾을 수 있습니다. 당신이 하나있어 일단 당신이 제안, 그것은 replaceWith를 사용하여 교체 쉽게입니다 :

>>> from BeautifulSoup import BeautifulSoup, CData, Tag 
>>> source = """ 
... <title>The end of the world as we know it</title> 
... <category><![CDATA[Planking Dancing]]></category> 
... <pubDate><![CDATA[Sun, 16 Sep 2012 12:00:00 EDT]]></pubDate> 
... <dc:creator><![CDATA[Bart Simpson]]></dc:creator> 
... """ 
>>> soup = BeautifulSoup(source) 
>>> for navstr in soup(text=True): 
...  if isinstance(navstr, CData): 
...   tag = Tag(soup, "myTag") 
...   tag.insert(0, navstr[:]) 
...   navstr.replaceWith(tag) 
... 
>>> soup 

<title>The end of the world as we know it</title> 
<category><myTag>Planking Dancing</myTag></category> 
<pubdate><myTag>Sun, 16 Sep 2012 12:00:00 EDT</myTag></pubdate> 
<dc:creator><myTag>Bart Simpson</myTag></dc:creator> 

>>> 

노트의 몇 :이 함수 것처럼

  • 당신이 BeautifulSoup 객체를 호출 할 수 있습니다, 효과는 .findAll() 메서드 호출과 동일합니다.

  • BS3에서 CData 개체의 콘텐츠를 얻는 방법은 위의 스 니펫과 마찬가지로 으로 슬라이스하는 것입니다. str(navstr)은 모두 <![CDATA[...]]>을 그대로 유지하므로 분명히 원하지 않습니다. BS4에서 str(navstr) 은 정크가없는 콘텐츠를 제공합니다.