92247


5GBのxmlファイルを読み取り,soup-containsで1万行辺りのテキストファイルの数値がarticle-
id_pmidだったら特定の文字列を含んだparagraphのテキストを抽出するというプログラムがあります.

このプログラムではBeautiful
Soupを用いてテキストを抽出しているのですが、それだとkilledと表示されてしまい、メモリ不足ではないかと思い、1.xmlのような形に分割処理をしたいでのすが、可能なのでしょうか.

**ソースコード**

[code]

    from bs4 import BeautifulSoup
    
    #xmlファイル読み込み
    with open('1.xml','r',encoding='utf-8') as xml:      
        soup = BeautifulSoup(xml, 'xml')
    
    # IDが書かれたテキストファイルを改行コードで区切る
    with open('1.txt') as b:
      nums =[n.strip() for n in b.readlines()]
    b.close()
    
    nums= ','.join(f'"{n}"' for n in nums)
    
    texts = soup.select(f'''
        document:has(>passage >infon[key="article-id_pmid"]:-soup-contains({nums})) >
            passage >
                infon[key="type"]:-soup-contains("paragraph") ~ text:-soup-contains("first") 
    ''')
    text = [t.text for t in texts]
       
    xml.close()
    
    #実行結果を指定のファイルに保存
    with open ('2.txt','w')as txt:
      print(text,file=txt)
    txt.close
    
[/code]

### 1.xml

[code]

        <collection>
            <document>
                <passage>
                    <infon key="article-id_pmid">1111</infon>
                </passage>
                <passage>
                    <infon key="type">paragraph</infon>
                    <text>which was first diagnosed in Wuhan. </text>
                </passage>
            </document>
       <collection>
    
[/code]


CC BY-SA 4.0
2022-11-14T01:28:44.727
92211
2022-11-16T00:40:41.273
2022-11-16T00:40:41.273
3060
54656
question
python python3 xml beautifulsoup
Beautiful Soup で 5GB のファイルを読み取り中、killed と表示されてしまう


<https://qiita.com/haminiku/items/faa6e4f20b4d94896834>  
こちらのサイトにまさにやりたいことがのってるのでは？

とりあえずメモリ問題を解決するだけで  
2.txt への書き込みはそのままなのでやりたいことができてるかは不明ですが

[code]

    from bs4 import BeautifulSoup
    
    # 参考：https://qiita.com/haminiku/items/faa6e4f20b4d94896834
    
    def file_read_generator(file_path, start, end):
        """
        XMLをパースして satrt 〜 end を読み込み返却するgenerator
        :rtype: str
        """
        f = open(file_path, 'r')
        count = 0
        txt = ''
    
        # Fileを1行ずつ読む
        for line in f:
            count += 1
            if start in line:
                txt = ''
            txt += line
            if end in line:
                result = txt
                txt = ''
                yield result
    
            if count % 1000 == 0:
                print(f'read {count} line')
    
    
    with open('1.txt') as b:
        # IDが書かれたテキストファイルを改行コードで区切る
        nums =[n.strip() for n in b.readlines()]
    nums= ','.join(f'"{n}"' for n in nums)
    
    
    #実行結果を指定のファイルに保存
    with open ('2.txt','w')as txt:
        for body in file_read_generator('1.xml', '<document>', '</document>'):
            # parseする
            soup = BeautifulSoup(body)
            texts = soup.select(f'''
                document:has(>passage >infon[key="article-id_pmid"]:-soup-contains({nums})) >
                    passage >
                        infon[key="type"]:-soup-contains("paragraph") ~ text:-soup-contains("first") 
            ''')
            text = [t.text for t in texts]
            print(text,file=txt)
    
[/code]


CC BY-SA 4.0
2022-11-15T14:01:20.440
92247
2022-11-15T14:01:20.440
92211
answer