2017-01-22 1 views
2

태그의 모든 이름 모르고 XML 파일의 태그와 텍스트 얻는 방법 :파이썬 아름다운 스프 심지어이 같은 XML 파일이

<a> 
    <b>1</b> 
    <c>2</c> 
    <d> 
    <e>3</e> 
    </d> 
</a> 
<a> 
    <c>4</c> 
    <f value ="something">5</f> 
    <g value = "other"></g> 
</a> 

을하고 내가 가진 dicts의 목록을 원하는 태그 및 텍스트. 예컨대 :

[{'b':1, 'c':2, 'e':3}, {'c':4, 'f value="something"':5, 'g value = "other"':None}] 

그것은 큰 XML 파일 그리고 그것은 표준 없습니다, 그래서 난 단지 <a>가 존재하는 것을 알고 나는이 태그 내부의 모든 정보를 원한다.

나는 Beautiful Soup 4를 이미 시도했지만 텍스트 부분 만 검색 할 수있었습니다.

내 코드

def ProcessXml(xmlFile): 
    infile = open(xmlFile, 'r') 
    contents = infile.read() 
    soup = BeautifulSoup(contents,'xml') 
    units = soup.find_all('a') 
    unitsList = [] 
    for i in units: 
     resultType = i.text,i.next_sibling 
     resultType = resultType[0].splitlines() 
     for j in resultType: 
      if j == '': 
       resultType.remove(j) 
     unitsList.append((resultType)) 

    return unitsList 

내 출력 :

[['1','2','3'],['4','5']] 
+0

이것은 bs4에서 가능합니다. 그 중 어떤 부분이 당신에게 효과가 없었습니까? – TankorSmash

+0

필자는 bs4와 python을 처음 접했을 뿐이다. 단위 = soup.find_all ('a') 단위는 : resultType = i.text, i.next_sibling @TankorSmash 고맙다 – 1pa

+0

편집 할 수 있습니까? 귀하의 질문에? 그러면 다른 사람들이 귀하의 질문에 답변하는 데 도움이됩니다. 포맷되지 않은 코드를 읽기가 어렵습니다. – TankorSmash

답변

2

정말 나쁜 코드입니다하지만 작업을 수행합니다

def len_descendant(desc): 
    counter = 0 
    try: 
     for i in desc.descendants: 
      if i!='' and i !='\n': 
       counter += 1 
    except Exception: 
     pass 
    return counter 

def ProcessXml(): 
    infile = open("xmlfile.xml", 'r') 
    contents = infile.read() 
    soup = BeautifulSoup(contents,'lxml') 
    units = soup.find_all('a') 
    unitsList = [] 
    for i in units: 
     this_dict = {} 
     for desc in i.descendants: 
      print desc, len_descendant(desc) 

      try: 
       if desc.has_attr('value'): 
        has_attribute = True 
      except Exception: 
       has_attribute = False 

      if len_descendant(desc)==1 or has_attribute: 
       if desc.has_attr('value'): 
        key = desc.name + " " + desc.attrs.keys()[0] + '=\"' + desc.attrs.values()[0] + '\"' 
       else: 
        key = desc.name 

       try: 
        value = int(desc.text) 
       except Exception: 
        value = None 
       this_dict[key] = value 
     unitsList.append(this_dict) 

    return unitsList 

my_dict = ProcessXml() 

결과는 다음과 같습니다

[{'c': 2, 'b': 1, 'e': 3}, {'f value="something"': 5, 'c': 4, 'g value="other"': 1}] 

참고 :

<a> 
    <b>1</b> 
    <c>2</c> 
    <d> 
    <e>3</e> 
    </d> 
</a> 
<a> 
    <c>4</c> 
    <f value ="something">5</f> 
    <g value = "other">1</g> 
</a> 
+0

고맙습니다. @Stergios 한 가지 더, 정말 필요합니다. { 'g vale = "other": None}과 같은 것을 반환하지만, 알아낼 수 없습니다. – 1pa

+0

위의 코드를 업데이트했습니다. 그것은 최악의 코드이지만 일을합니다 :) – Stergios

+0

대단히 감사합니다 !! 같은 시간에 코드를 게시하지만 코드가 더 좋아 보인다 :) – 1pa

0
def len_descendant(desc): 
    counter = 0 
    try: 
     for i in desc.descendants: 
      #print (i) 
      if i!='' and i !='\n': 
       counter += 1 
    except Exception: 
     pass 
    return counter 

def ProcessXmlTwo(fileName): 
    infile = open(fileName, 'r') 
    contents = infile.read() 
    soup = BeautifulSoup(contents,'xml') 
    units = soup.find_all('a') 
    #print (units) 
    unitsList = [] 
    for i in units: 
     this_dict = {} 
     for desc in i.descendants: 
      flagNoKey = False 
      if len_descendant(desc)==1 or 'value="true"/>' in str(desc) or 'value="false"/>' in str(desc): 
       if desc.has_attr('value'): 
        #print (desc.name) 
        key = desc.name + " " + list(desc.attrs.keys())[0] + '=\"' + list(desc.attrs.values())[0] + '\"' 
       elif 'value="true"/>' in str(desc) or 'value="false"/>' in str(desc): 
        flagNoKey = True 
        key = desc.name + " " + list(desc.attrs.keys())[0] + '=\"' + list(desc.attrs.values())[0] + '\"' 
       else: 
        key = desc.name 
       if flagNoKey == False: 
        this_dict[key] = desc.text 
       else: 
        this_dict[key] = "None" 

     unitsList.append(this_dict) 

    return unitsList 

이 내가 사용하는 코드는 다음과 같습니다 MYGz 언급했듯이 나는 이것이 내가의 기능을 시도 XML 파일입니다, 그래서 'g value = "other"'}] 부분이 잘못되었습니다. 이것은 @Stergios가 작성한 코드의 개조입니다. (파이썬 3에서 작동)