簡體   English   中英

使用 rdd.map 將 html 轉換為 json

[英]convert html to json using rdd.map

我有 html 文件,我想在 pySpark 中解析它。

例子:

<MainStruct Rank="1">
  <Struct Name="A">
    <Struct Name="AA">
      <Struct Name="AAA">
        <Field Name="F1">Data</Field>
      </Struct>
      <Struct Name="ListPart">
        <List Name="ListName">
          <Struct Name="S1">
            <Field Name="F1">AAA</Field>
            <Field Name="F2">BBB</Field>
            <Field Name="F3">CCC</Field>
          </Struct>
          <Struct Name="S1">
            <Field Name="F1">XXX</Field>
            <Field Name="F2">GGG</Field>
            <Field Name="F3">BBB</Field>
          </Struct>
        </List>
      </Struct>
    </Struct>
  </Struct>
</FullStudy>
rdd_html = spark.sparkContext.wholeTextFiles(path_to_XML, minPartitions=1000, use_unicode=True)
df_html = spark.createDataFrame(rdd_html,['filename', 'content'])
rdd_map = df_html.rdd.map(lambda x: xmltodict(x['content'],'mainstruct'))
df_map = spark.createDataFrame(rdd_map)

df_map.display()

但在我的筆記本 output 中,我對列表元素有疑問。 它們被錯誤地解析。

>object
     >AA: 
       >ListPart: 
         ListName: "[{S1={F1=AAA, F2=BBB, F3=CCC}}, {S1={F1=XXX, F2=GGG, F3=BBB}}]"
     >AAA: 
        F1: "Data"

列表元素表示為一個字符串行。

我的 function 來解析它:

def xmltodict(content,first_tag=''):
   
    #Content from xml File
    content = re.sub('\n', '', content)
    content = re.sub('\r', '', content)
    content = re.sub('>\s+<', '><', content)

    data = unicodedata.normalize('NFKD', content)
    soup = BeautifulSoup(data, 'lxml')

    body = soup.find('body')

    if(first_tag.strip()!=''):
        struct = body.find(first_tag)
    else:
        struct=body

    return parser(struct)

def parser(struct):
    struct_all = struct.findAll(True, recursive=False)

    struct_dict = {}
    for strc in struct_all:
        tag = strc.name
        tag_name_prop = strc.attrs['name']  
    
        if tag == 'struct':
            d = parser(strc)
            el = {tag_name_prop: d}
            struct_dict.update(el)
        elif tag == 'field':
            v = strc.text
            struct_dict[tag_name_prop] = v
        elif tag == 'list':
            l_elem = []
            for child in strc.contents:
                soap_child = BeautifulSoup(str(child), 'lxml').find('body')
                l_elem.append(parser(soap_child))
                el = {tag_name_prop: l_elem}
                struct_dict.update(el)
    
    with open (result.txt,'w') as file:
        file.write(json.dumps(struct_dict))
        
    return struct_dict

txt 文件中的結果是我想接收:

"A": {   "AA": {
            "AAA": {"F1": "Data"},
             "ListPart": {
                "ListName": [
                    {
                        "S1": {"F1": "AAA",
                            "F2": "BBB",
                            "F3": "CCC" 
                                                       }
                    },
                    {
                        "S1": { "F1": "XXX",
                            "F2": "GGG",
                            "F3": "BBB"
                        }}]
            }}}

但在我的筆記本 output 中,我對列表元素有疑問。 它們被錯誤地解析。

>object
     >AA: 
       >ListPart: 
         ListName: "[{S1={F1=AAA, F2=BBB, F3=CCC}}, {S1={F1=XXX, F2=GGG, F3=BBB}}]"
     >AAA: 
        F1: "Data"

為什么列表表示為一個字符串行? 為什么有“=”符號而不是“:”?

我將這個問題簡化為:

    def parseList(row):
        d = {}
        d['el1']='AAA'
        l = [{'x1':'XA'},{'x1':'XB'}]
        d['el2']=l
        return Row(res=d)
rdd_html = spark.sparkContext.wholeTextFiles(path_to_file_test, minPartitions=1000, use_unicode=True)
df_html = spark.createDataFrame(rdd_html,['filename', 'content'])
rdd_map = df_html.rdd.map(parseList2)
df_map = spark.createDataFrame(rdd_map)
df_map.display()

結果我也有

>object
    el2: "[{x1=XA}, {x1=XB}]"
    el1: "AAA"

不是那個

>object
   >el2 
     x1:"XA"
     x1:"XB"
    el1: "AAA"

我終於解決了我的問題。 原因是我應該定義架構並使用它。

df_map = spark.createDataFrame(rdd_map,schema)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM