🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

958閲覧

pythonでXMLを非同期処理で読み取りたい

meoto2408

総合スコア52

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/12/26 14:56

編集2020/12/27 04:30

PythonでXMLを読み取りたい

Web上にあったものがどのように動作するのかを見ているときに非同期処理にしたいと思ったので、いじっていたのですが、うまく非同期処理ができませんでした。

ソースコードの"icon": Var.eicon(Intensity), "color": Var.eicolor(Intensity)という部分は問題なく返すことができるので、XMLファイルを開いて、その中身を取得するということをメインでしなければいけないことが分かってはいるので、python xml aiohttpなどで調べてはいるのですが、全然できずに丸一日潰しておりました。

どのようにすることで非同期処理にできるのでしょうか?
ヒントだけでもいいので教えていただけるとありがたいです

ソースコード

Web上にあったものを少し弄ったもの

python

1def e(): 2 eews = '' 3 xml_data_module = requests.get('https://URL/data1.xml') 4 xml_data_module.encoding = "Shift_JIS" 5 try: 6 root = ET.fromstring(xml_data_module.text) 7 for item in root.iter('item'): 8 eews = (item.attrib['url']) 9 break 10 deta1 = requests.get(eews) 11 deta1.encoding = "Shift_JIS" 12 try: 13 root = ET.fromstring(deta1.text) 14 e_1 = '' 15 for Earthquake in root.iter('Earthquake'): 16 time = (Earthquake.attrib['Time']) 17 Intensity = (Earthquake.attrib['Intensity']) 18 Epicenter = (Earthquake.attrib['Epicenter']) 19 Magnitude = (Earthquake.attrib['Magnitude']) 20 Depth = (Earthquake.attrib['Depth']) 21 map_url = 'https://www3.nhk.or.jp/sokuho/jishin/' 22 count = 1 23 for Area in root.iter('Area'): 24 e_1 += '\n' + Area.attrib['Name'] 25 if count == 10: 26 e_1 += '\n他' 27 break 28 count = count + 1 29 for Detail in root.iter('Detail'): 30 map = map_url + Detail.text 31 edic = {'time': time, 'epicenter': Epicenter, "intensity": Intensity, "depth": Depth, "magnitude": Magnitude, "map": map, "icon": eicon(Intensity), "color": eicolor(Intensity), 'e_1': e_1} 32 return edic 33 except Exception: 34 return 'error' 35 except Exception: 36 return 'error'

非同期処理しようとしたもの

python

1async def e(): 2 async with aiohttp.ClientSession() as session: 3 async with session.get(url='https://URL/file/data1.xml') as response: 4 xml_data = str(response) 5 try: 6 root = ET.fromstring(xml_data) 7 for item in root.iter('item'): 8 e_item = (item.attrib['url']) 9 break 10 async with session.get(url=e_item) as response1: 11 data1 = str(response1) 12 try: 13 root = ET.fromstring(data1) 14 e_1 = '' 15 for Earthquake in root.iter('Earthquake'): 16 time = (Earthquake.attrib['Time']) 17 Intensity = (Earthquake.attrib['Intensity']) 18 Epicenter = (Earthquake.attrib['Epicenter']) 19 Magnitude = (Earthquake.attrib['Magnitude']) 20 Depth = (Earthquake.attrib['Depth']) 21 map_url = 'https://URL/' 22 count = 1 23 for Area in root.iter('Area'): 24 e_1 += '\n' + Area.attrib['Name'] 25 if count == 10: 26 e_1 += '\n他' 27 break 28 count = count + 1 29 for Detail in root.iter('Detail'): 30 map = map_url + Detail.text 31 edic = {'time': time, 'epicenter': Epicenter, "intensity": Intensity, "depth": Depth, "magnitude": Magnitude, "map": map, "icon": Var.eicon(Intensity), "color": Var.eicolor(Intensity), 'e_1': e_1} 32 return edic 33 except Exception: 34 return 'error' 35 except Exception: 36 return 'error'

追記1

data1.xml

xml

1<jishinReport> 2<record date="2020年12月27日"> 3<item time="12時53分ごろ" shindo="1" url="https://URL/file/JSA0201227125306_20201227125546.xml">長野県南部</item> 4<item time="04時09分ごろ" shindo="1" url="https://URL/file/JSA0201227040909_20201227041157.xml">茨城県沖</item> 5</record> 6<record date="2020年12月26日"> 7<item time="18時25分ごろ" shindo="1" url="https://URL/file/JSA0201226182534_20201226182816.xml">岐阜県美濃中西部</item> 8<item time="06時32分ごろ" shindo="2" url="https://URL/file/JSA0201226063236_20201226063548.xml">岩手県沿岸北部</item> 9<item time="00時13分ごろ" shindo="1" url="https://URL/file/JSA0201226001319_20201226001539.xml">北海道渡島地方東部</item> 10</record> 11<record date="2020年12月25日"> 12<item time="23時22分ごろ" shindo="1" url="https://URL/file/JSA0201225232200_20201225232434.xml">鹿児島湾</item> 13<item time="13時12分ごろ" shindo="1" url="https://URL/file/JSA0201225131217_20201225131924.xml">熊本県熊本地方</item> 14<item time="06時27分ごろ" shindo="2" url="https://URL/file/JSA0201225062739_20201225063052.xml">宮城県北部</item> 15<item time="05時38分ごろ" shindo="2" url="https://URL/file/JSA0201225053846_20201225054236.xml">種子島近海</item> 16<item time="05時35分ごろ" shindo="1" url="https://URL/file/JSA0201225053514_20201225053818.xml">長野県中部</item> 17<item time="04時40分ごろ" shindo="2" url="https://URL/file/JSA0201225044015_20201225044331.xml">茨城県沖</item> 18</record> 19<record date="2020年12月24日"> 20<item time="21時58分ごろ" shindo="1" url="https://URL/file/JSA0201224215838_20201224220116.xml">岐阜県美濃中西部</item> 21<item time="08時11分ごろ" shindo="2" url="https://URL/file/JSA0201224081149_20201224081451.xml">豊後水道</item> 22<item time="03時18分ごろ" shindo="2" url="https://URL/file/JSA0201224031915_20201224032300.xml">京都府南部</item> 23<item time="02時55分ごろ" shindo="3" url="https://URL/file/JSA0201224025558_20201224025946.xml">三重県南部</item> 24</record> 25<record date="2020年12月23日"> 26<item time="22時08分ごろ" shindo="1" url="https://URL/file/JSA0201223220844_20201223221144.xml">宮城県沖</item> 27<item time="09時03分ごろ" shindo="1" url="https://URL/file/JSA0201223090306_20201223090609.xml">茨城県沖</item> 28<item time="06時34分ごろ" shindo="1" url="https://URL/file/JSA0201223063447_20201223063756.xml">新島・神津島近海</item> 29<item time="03時24分ごろ" shindo="1" url="https://URL/file/JSA0201223032445_20201223032817.xml">奄美大島北西沖</item> 30<item time="02時04分ごろ" shindo="1" url="https://URL/file/JSA0201223020408_20201223020853.xml">福島県沖</item> 31</record> 32<record date="2020年12月22日"> 33<item time="16時30分ごろ" shindo="1" url="https://URL/file/JSA0201222163059_20201222163331.xml">新島・神津島近海</item> 34<item time="11時52分ごろ" shindo="1" url="https://URL/file/JSA0201222115204_20201222115454.xml">岐阜県飛騨地方</item> 35<item time="01時28分ごろ" shindo="1" url="https://URL/file/JSA0201222012850_20201222013130.xml">福島県浜通り</item> 36<item time="00時41分ごろ" shindo="1" url="https://URL/file/JSA0201222004142_20201222004458.xml">栃木県北部</item> 37</record> 38<record date="2020年12月21日"> 39<item time="06時32分ごろ" shindo="1" url="https://URL/file/JSA0201221063214_20201221063512.xml">熊本県熊本地方</item> 40<item time="02時23分ごろ" shindo="5-" url="https://URL/file/JSA0201221022252_20201221042011.xml">青森県東方沖</item> 41<item time="02時04分ごろ" shindo="1" url="https://URL/file/JSA0201221020418_20201221020727.xml">新島・神津島近海</item> 42<item time="01時25分ごろ" shindo="2" url="https://URL/file/JSA0201221012528_20201221012843.xml">北海道日高地方東部</item> 43<item time="00時39分ごろ" shindo="3" url="https://URL/file/JSA0201221003912_20201221004231.xml">新島・神津島近海</item> 44</record> 45</jishinReport>

それぞれのURLの形式

xml

1<Root> 2<Timestamp>2020/12/23 22:11:44</Timestamp> 3<Earthquake Id="A0201223220844" Time="2020/12/23 22:08:00" Intensity="1" Epicenter="宮城県沖" Latitude="北緯 38.9度" Longitude="東経 142.6度" Magnitude="4.1" Depth="40km"> 4<Detail>data/JS00cwA0201223220844_20201223221144.jpg</Detail> 5<Local>data/JS00cuA0201223220844_20201223221144.jpg</Local> 6<Global>data/JS00clA0201223220844_20201223221144.jpg</Global> 7<Relative> 8<Group Intensity="1"> 9<Area Name="大船渡市"/> 10<Area Name="一関市"/> 11<Area Name="住田町"/> 12<Area Name="気仙沼市"/> 13<Area Name="南三陸町"/> 14</Group> 15</Relative> 16</Earthquake> 17</Root>

追記2

問題点としてはこのシステムを動かしているサーバが非同期処理をしないとすぐに固まってしまうため、非同期処理にしたいと思っています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/12/27 16:48 編集

削除
guest

回答1

0

ベストアンサー

aiohttpで取得したレスポンスからテキストを得る場合は、
awaitをつけてtext()関数を使う必要があります。

また、requestsと異なり、エンコーディングを指定する場合は、text()内でencoding引数を指定してやる必要があります。

たとえば、e()の最初の部分、

async def e(): async with aiohttp.ClientSession() as session: async with session.get(url='https://URL/file/data1.xml') as response: xml_data = str(response) # <--------ここが間違っているので正しく動作しない。

は、修正すると

async with aiohttp.ClientSession() as session: async with session.get(url='https://URL/file/data1.xml') as response: xml_data = await response.text(encoding='Shift_JIS') #<------------修正

となります。

中段の

async with session.get(url=e_item) as response1: data1 = str(response1)

も同様に直す必要があります。

また 本件で、async def e()を呼び出すには、下記のようにします。
(e()の後に書けばよいです)

loop = asyncio.get_event_loop() results = loop.run_until_complete(e()) # 結果を出力 print(results)

[全体(直した後)]:

import asyncio import aiohttp import xml.etree.ElementTree as ET class Var:  (不明) async def e(): async with aiohttp.ClientSession() as session: async with session.get(url='https://URL/file/data1.xml') as response: xml_data = await response.text(encoding="Shift_JIS") try: root = ET.fromstring(xml_data) for item in root.iter('item'): e_item = (item.attrib['url']) break async with session.get(url=e_item) as response1: data1 = await response1.text(encoding="Shift_JIS") try: root = ET.fromstring(data1) e_1 = '' for Earthquake in root.iter('Earthquake'): time = (Earthquake.attrib['Time']) Intensity = (Earthquake.attrib['Intensity']) Epicenter = (Earthquake.attrib['Epicenter']) Magnitude = (Earthquake.attrib['Magnitude']) Depth = (Earthquake.attrib['Depth']) map_url = 'https://URL/' count = 1 for Area in root.iter('Area'): e_1 += '\n' + Area.attrib['Name'] if count == 10: e_1 += '\n他' break count = count + 1 for Detail in root.iter('Detail'): map = map_url + Detail.text edic = {'time': time, 'epicenter': Epicenter, "intensity": Intensity, "depth": Depth, "magnitude": Magnitude, "map": map, "icon": Var.eicon(Intensity), "color": Var.eicolor(Intensity), 'e_1': e_1} return edic except Exception: return 'error' except Exception: return 'error' loop = asyncio.get_event_loop() results = loop.run_until_complete(e()) print(results)

投稿2020/12/27 16:47

編集2020/12/27 16:52
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meoto2408

2020/12/29 07:01

.text()を使う必要があったのですね... ご回答、ありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問