如何使用BeautifulSoup从xml提取文本和标签属性

时间:2019-11-17 18:15:24

标签: python regex xml beautifulsoup

我想从xml下面提取文本以及宽度,高度,顶部,左侧和页面编号,并将其附加到数据框。

   <page number="1" position="absolute" top="0" left="0" height="1188" width="918">
       <fontspec id="0" size="21" family="MOFZXD+AvenirNext-DemiBold" color="#231f20"/>
       <fontspec id="1" size="25" family="MOFZXD+MyriadPro-Regular" color="#231f20"/>

       <text top="375" left="708" width="168" height="33" font="0"><b>LISTING # 1131</b></text>
       <text top="1049" left="657" width="92" height="32" font="1">1.03 +/- </text>
       <text top="1049" left="750" width="51" height="35" font="1">Acre</text>
       <text top="1089" left="657" width="178" height="27" font="2">Tax Map and Parcel:</text>
   </page>


   <page number="2" position="absolute" top="0" left="0" height="1188" width="918">
       <fontspec id="6" size="23" family="MOFZXD+Baskerville" color="#57585a"/>
       <fontspec id="7" size="10" family="LGVTJF+Avenir-Roman" color="#231f20"/>
       <text top="827" left="681" width="107" height="33" font="6">Andy Cox </text>
       <text top="861" left="681" width="186" height="17" font="7">COMMERCIAL SALES SPECIALIST</text>
   </page>

我尝试使用下面的代码,但结果仅包含重复的值。

for message in soup.findAll('page'):
    page_number = re.findall(r'number=\"(\d*?)\"', str(message))[0]
    for text in soup.findAll('text'):
        content = text.text

        #print(font_value)
        height_value = re.findall(r'height="(\d*?)"',str(text))[0]
        left_value = re.findall(r'left="(\d*?)"',str(text))[0]
        top_value = re.findall(r'top="(\d*?)"',str(text))[0]
        width_value = re.findall(r'top="(\d*?)"',str(text))[0]

        df = df.append({'Page Number':page_number,'Content':content,'Top':top_value,'Left':left_value,'Width':width_value,'Height':height_value},ignore_index=True)

结果

    Page Number Content     Top Left    Width   Height
1   LISTING  #1131  375 708 375 33
1   1.03 +/-    1049    657 1049    32
1   Acre    1049    750 1049    35
1   Tax Map and Parcel: 1089    657 1089    27
2   Andy Cox    827 681 107 33
2   COMMERCIAL SALES SPECIALIST 861 681 186 17

2 个答案:

答案 0 :(得分:2)

使用BeautifulSoup查找所需的标签并从标签中提取信息。

import operator
from bs4 import BeautifulSoup
whatiwant = operator.itemgetter('top','left','width','height')
#soup = BeautifulSoup(s,'lxml')
soup = BeautifulSoup(s,'html.parser')
for page in soup.findAll('page'):
    for t in page.findAll('text'):
        print(page['number'], t.text, whatiwant(t))

答案 1 :(得分:0)

我选择使用BeautifulSoup一次解析XML,它工作得很好。我在您的数据中添加了一个根标记,以便我的IDE不再抱怨。

代码:

import pandas as pd
from bs4 import BeautifulSoup

col_names = ['page_number', 'elem_text', 'elem_top', 'elem_left', 'elem_width', 'elem_height']

with open('../resources/page_text_xml_data.xml') as file_in:
    soup = BeautifulSoup(file_in, features='xml')

row_dicts = []

for curr_page in soup.find('root').find_all('page', recursive=False):
    curr_page_num = curr_page['number']
    for curr_text_elem in curr_page.find_all('text', recursive=False):
        row_dicts.append(
            {'page_number': curr_page_num, 'elem_text': curr_text_elem.text.strip(), 'elem_top': curr_text_elem['top'],
             'elem_left': curr_text_elem['left'], 'elem_width': curr_text_elem['width'],
             'elem_height': curr_text_elem['height']})

df_1 = pd.DataFrame(row_dicts)

DataFrame内容:

      page_number  elem_text                      elem_top    elem_left    elem_width    elem_height
--  -------------  ---------------------------  ----------  -----------  ------------  -------------
 0              1  LISTING # 1131                      375          708           168             33
 1              1  1.03 +/-                           1049          657            92             32
 2              1  Acre                               1049          750            51             35
 3              1  Tax Map and Parcel:                1089          657           178             27
 4              2  Andy Cox                            827          681           107             33
 5              2  COMMERCIAL SALES SPECIALIST         861          681           186             17

让我知道您是否有任何问题:)