Katsuhisa_Deto
@Katsuhisa_Deto

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

質問:XMLファイルのWebスクレイピングにおける欠損値処理

解決したいこと

pythonでXMLファイルを対象に、Webスクレイピングをしています。
XMLファイルに含まれる欠損値・項目として存在しないタグの内容を出力できるようにしたいです。

具体的な内容

タグの値が「1」<AB56222>1</AB56222>の際に、その次に出力されるべきタグ<AB56225>???</AB56225>自体が出力されない仕様のXMLファイルがあります。
その際、<AB56225>nan</AB56225>と出力されるように変更したいです。

XMLファイルの中身

xml
<?xml version="1.0" encoding="UTF-8"?>
<ABM55525>
    <ABMR55525>
        <AB56455>aaa</AB56455>
        <AB56225>Mike</AB56225>
        <AB56222>DK55552</AB56222>
        <AB56222>0</AB56222>
        <AB56225>2.4</AB56225>
    </ABMR55525>
    <ABMR55525>
        <AB56455>aab</AB56455>
        <AB56225>Tom</AB56225>
        <AB56222>DK55552</AB56222>
        <AB56222>1</AB56222> ← ココ。次の行に<AB56225>nan</AB56225>が出力されるようにしたい。
    </ABMR55525>
    <ABMR55525>
        <AB56455>aac</AB56455>
        <AB56225>Cathy</AB56225>
        <AB56222>DK55552</AB56222>
        <AB56222>0</AB56222>
        <AB56225>2.8</AB56225>
    </ABMR55525>
</ABM55525>

該当箇所

該当箇所(14行目)
        <AB56222>1</AB56222>

実現したい修正後の形

        <AB56222>1</AB56222>
        <AB56225>nan</AB56225>

自分で試したこと

1 . replaceメソッドを使用

python
xml_a = open(file_a, 'r', encoding='utf-8').read()
soup = BeautifulSoup(xml_a, 'xml')

# 文字列として置換
soup.replace(str('<JP56222>1</JP56222>'),str('<JP56222>0</JP56222>\n<JP56225>nan</JP56225>'))

結果:エラー

----> soup.replace(str('<JP56222>1</JP56222>'),str('<JP56222>0</JP56222>\n<JP56225>nan</JP56225>'))

TypeError: 'NoneType' object is not callable

2 . append, insert_afterメソッドを使用
以下記事を参考に、タグの要素に対してタグや文字列の追加を行う
https://senablog.com/python-bs4-modification/#

python
xml_a = open(file_a, 'r', encoding='utf-8').read()
soup = BeautifulSoup(xml_a, 'xml')

soup = BeautifulSoup("<AB56222>1</AB56222>", 'html.parser')
new_tag = soup.new_tag('AB56225')
new_tag.string = 'nan'
soup.ab56222.string.insert_after(new_tag)
soup

結果:タグの中にnanが入れ込まれる

<ab56222>1<AB56225>nan</AB56225></ab56222>

期待した結果を得るようにするために、どのようにコードを修正すべきか、使える新しいメソッドなどがあれば教えてください。
よろしくお願いします。

0

1Answer

2の

soup.ab56222.string.insert_after(new_tag)

soup.ab56222.insert_after(new_tag)

に変えればよさそうです。

0Like

Comments

  1. @Katsuhisa_Deto

    Questioner

    @uasi さんありがとうございます!

    <AB56225>nan</AB56225>が<AB56222>1</AB56222>の外側(右)に表示されました。(以下のように)
    ```
    <AB56222>1</AB56222><AB56225>nan</AB56225>
    ```
    実際には、<AB56225>nan</AB56225>を改行して出力したいのですが、どのようにすれば改行はできるのでしょうか?
    ```
    <AB56222>1</AB56222>
    <AB56225>nan</AB56225>
    ```

    また、「実現したい修正後の形」を元のXMLファイルに下記のように反映させることはどうすれば可能なのでしょうか?
    ```
    <ABMR55525>
    <AB56455>aab</AB56455>
    <AB56225>Tom</AB56225>
    <AB56222>DK55552</AB56222>
    <AB56222>1</AB56222>
    `<AB56225>nan</AB56225>`
    </ABMR55525>
    ```
    色々と自分で試したのですが方法が分からず、追加の質問になりますが教えていただけますと幸いです。
  2. insert_after は文字列やタグを複数まとめて挿入できます。 insert_after('\n', new_tag) のように改行を入れてください。

    元のファイルに反映させるには、普通に元のファイルを書き込みモードで開いて str(soup) を書き込んでください。

    その他の使い方は BeautifulSoup のマニュアルを読んでください https://www.crummy.com/software/BeautifulSoup/bs4/doc/
  3. @Katsuhisa_Deto

    Questioner

    ご丁寧に回答いただきありがとうございます。解決できるように頑張ります。
    また、マニュアルをしっかりと読んでみます。

Your answer might help someone💌