質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

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

Q&A

解決済

1回答

798閲覧

Python スクレイピング 2次元配列格納

rrrrrrrry

総合スコア20

Python 3.x

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

0グッド

0クリップ

投稿2018/08/07 23:16

編集2018/08/08 14:23

前提・実現したいこと

質問内容に変更がありましたので一旦枠を変えました。
指定したクエリを含む分を取得しています。またその前後の文を取得するプログラムを作りました。
それらの関係性を調べていくためにgurunaviからコメントをスクレイピングしている最中に今していることを2次元配列に格納していきたかったのですが、プログラム中のcommentLinesをどのように二次元配列用に初期化したらいいかわからないので教えていただきたいです。また、下の実行例のように空白部分にNULLを入れる方法もわからなかったので教えていただきたいです。

今回指定しているクエリはとんかつです。

(0,0)にとんかつと含まれる文章。(0,1)にその文章をiとしたらi-1の文章。(0,2)にi+1,(0,3)にi-2...
というように入れていきたいです。
そして次のとんかつと含まれるレビューが見つかったら(1,0)にその文章というように格納したいです。

かなりわかりづらい質問になってしまったため何か補足情報等必要でしたらお願いいたします。

例 とんかつは美味しい。ソース味がした。そのとんかつは大きかった。美味しかった!

だとしたら
(0,0)=とんかつは美味しい
(0,1)=''
(0,2)=ソース味がした
(0,3)=''
(0,4)=そのとんかつは大きかった
.
.
.
(1,0)=そのとんかつは大きかった
(1,1)=ソース味がした
(1,2)=美味しかった
(1,3)=とんかつは美味しい
(1,4)=''

(2,x)以降は次のレビューのとんかつと含まれる文からまたそれを行っていきます。

元のレビュー文(試験的に店名,メニュー名も読み取っている)

50件ヒットしました。 ---- 遊食菜彩いちにいさん とんかつ とってもジューシー 矢場とん 矢場町本店 わらじとんかつ とにかくボリュームがすごいです。 みそも甘くて美味しい! すずや とんかつ茶づけ ソースではなくしょっぱく味付けされたキャベツでいただく風変わりなとんかつ。シメはお茶をかけてお茶漬けにしてサッパリと。 旬菜酒処 とんかつ かつ繁 とんかつ 肉厚で美味しいです 黒ぶたやルミネ横浜店 黒豚とんかつ 日本人大好き黒豚とんかつ 遊食菜彩いちにいさん とんかつ 厚切りとんかつ。食べ応え満点 とんかつ 勝泉 とんかつ ころもがさくさくです とんかつがんこ梅三小路店 一口とんかつ膳 矢場とん 矢場町本店 わらじとんかつ 横綱の豚が目印のお店。 わらじとんかつは大きさも味のよさも横綱級。 名古屋にきたら立ち寄るべし。 矢場とん東京 銀座店 みそとんかつ この日はひれとんかつをいただきました! お肉もとても柔らかいし、とてもボリュームがあり、お値段以上の満足度でした♪ でももうちょっと味噌だれがほしかったかな… 次は味噌だれとソースのハーフ&ハーフという贅沢メニューにトライしようかな~っと思っています☆ すずや とんかつ茶づけ 特製の醤油たれがしっかりとついたトンカツを最後はお茶漬けにして食べるので こってりしすぎないところが良い。 とんかつ 江戸家 とんかつ ジューシーなとんかつ。ボリュームも丁度良くて美味! すずや秋葉原店 温泉玉子のせ とんかつ茶づけ 素材の味を生かしたさっぱりした味わいです。 世界のやまちゃん本店 名古屋のみそとんかつ 名古屋のちょっと甘い味噌だれがだっぷりとかかっていて、ビールにあう一品でした。 丸八とんかつ 本店 とんかつ リーズナブルでガッツりととんかつが食べられます。 みそかつ 矢場とん 名古屋駅エスカ店 わらじとんかつ 名物のみそかつと、ソースかつの2つを同時に食べられる、贅沢なメニューです。定食もあって、ご飯やお味噌汁と一緒にボリュームたっぷりな一品になります。 矢場とん東京 銀座店 わらじとんかつ 名古屋の有名店ですが、銀座で食べられます。わらじはすごいボリュームですが、味噌と通常ソースの合いがけもできます。 名代とんかつ かつくら三条本店 とんかつ膳 とんかつが食べたくなるなら絶対ココ!お肉もジューシーです 矢場とん東京 銀座店 鹿児島産黒豚ひれとんかつ 黒豚がおいしくいただけました。 黒豚はお値段少々しますが、他の物は1000円くらいなのでみそかつ食べたい方はこちらおすすめです。 矢場とん東京 銀座店 ロースとんかつ 初味噌かつ!普通のとんかつソースも選べましたがやはり味噌で食べました。 トンカツの店 豚珍館 とんかつ定食 ボリューム満点 おかわり自由 メニューの品数豊富 とんかつ専門店 かつ屋 とんかつ ハンバーグ、鳥の唐揚げ、串カツ、コロッケがあって盛りだくさん ごはんとキャベツはおかわり自由! 矢場とん 矢場町本店 わらじとんかつ 矢場とんと言えば、やっぱり「わらじとんかつ」でしょう!独特のソースがたまりません。かなりのボリュームなのにペロリです。 とんかつ店 みのや とんかつ定食 学生時代から480円が、一度だけの値上げで500円を現在でも変わらぬ値段です。カツも大きくて、ご飯はお皿にいっぱい!そして豚汁は丼で出てきます。コレだけ揃って500円。。。そのほかにビフカツ、豚テキ、ビフテキ、各種揚げ物…組み合わせて定食にできます。昔ながらの定食屋?引っ越した今でも時々通いつめ、もう20年以上の付き合いです。 とんかつ和佳葉 ロースとんかつ定食 揚げたてサクサクでお肉がとても柔らかいです♪ 特にヒレ肉は柔らかくてオススメとのことでした(^^)! また、付け合せの野菜以外に、マカロニサラダも付いていました(^O^) これもとても美味しかったです♪ アグーしゃぶしゃぶと沖縄料理おJi~ ミルフィーユとんかつ ボリューム満点のミルフィーユのとんかつ。 あっさりと食べられました 名代とんかつ かっぱ ミニとんかつ定食 とんかつで有名な「かっぱ」のお手頃・ちょうど良い量のトンカツのセットと言えば「ミニとんかつ定食」。ミニと言っても十分な大きさがあり、ライスと千切りキャベツ、ポテト&マカロニサラダとお味噌汁がついています。ソースはカレー風味に感じ、スパイシーで、サクサクの衣に熱々のお肉がとても美味しかったです。ちなみに名代とんかつの単品は900円です。 長八 とんかつ定食 看板通りおすすめのとんかつが嬉しい定食に。とんかつは肉にコダワリが有るらしいが、 揚げ油がサッパリしているので、良質の豚肉の味がしっかりと味わえる。 ごはん、味噌汁、キャベツはお代わり自由。 味噌汁は+50円で豚汁に変更出来るのも嬉しい。 みそかつ 矢場とん 名古屋駅エスカ店 わらじとんかつ 名古屋名物の味噌のソースがかかった巨大なとんかつです。味が濃い目で、白いご飯がすすみます。お肉はとてもやわらかいです。おなかをペコペコにしていきたいお店です。 CoCo壱番屋平野瓜破店 手仕込とんかつカレー なんと言ってもボリューム満点なところがいいですね。とんかつがかなりさくさく感があり、お肉が柔らかくて、ルーとの相性がいいですよね。 平野屋 風雅とんかつ お肉はとても柔らかく、ボリュームがあってとても美味しかったです。 遊食菜彩いちにいさん とんかつ定食 1350円と少々値段はしますが今まで食べたとんかつの中で一番美味しいです。 遊食菜彩いちにいさん とんかつ 衣がサクサクでお肉も1センチくらいで分厚く、がっつり食べたい時には重宝するお店です。 ランチはとても混んでいて、早めの来店がお勧め。 すずや とんかつ茶づけ すずや名物の「とん茶」、画像は「大サイズ」  食べ方は、初めに普通に食べて残り3切れぐらいになったらお茶漬けにします。 とんかつのお茶漬けは、賛否両論がありそうかも!? すずやに行ったら、1度は注文したいメニューだと思います♪ かつ太郎本店 水戸店 やわらかとんかつ十二単定食 ご飯は白米か雑穀米?選べます。 カツは見た目ちょっと小さい印象。 (前回はランチだったけど、もっとおっきかったような) お味も、ジューシーさがあんまりなくて、さっぱり。 1554円 すずや とんかつ茶づけ ちょっとレトロな店内で、とんかつをお茶漬けにするなんて、と過去にショックを受けたメニューのひとつです。 最初は鉄板に乗ったそのままで、次にほうじ茶をかけてお茶漬けにして。ごはん、キャベツがおかわり自由なので足りない人は追加できます。 さくさくのとんかつは、やっぱりできたてがおいしい! かつ善 通常とんかつ定食 すずや とんかつ茶づけ 名物と聞いていただきました。とんかつとキャベツをご飯に乗っけてお茶漬けで食べるというジャンクフードのノリで食べられる料理でした。量がけっこうガッツリです! 和食麺処サガミ千音寺店 とんかつ定食 とんかつのソースはお味噌かソース選べます。迷って両方用意してくださいました。 矢場とん 名古屋駅名鉄店 わらじとんかつ わらじとんかつ定食1680円 味噌ソースのカツと普通のトンカツの2枚がセットになった定食 味噌ソースは甘めの八町味噌でごはんがすすみます 小春軒 とんかつ盛合せライス とんかつ盛合せライス950円を食しました。 ロースカツとヒレカツ、そしてライスが付いてきます。 とんかつは上品で柔らかい豚肉を使って、カリカリジューシーに揚げてあります。 この場所でこのボリュームでこの値段は、かなりお得ですよね。 美味しいランチを楽しめました。 矢場とん 中部国際空港店 鉄板とんかつ 見た目ほど量が多くないです。鉄板が熱々で煙を上げながら出てきます。 世界の山ちゃん広島大手町店 名古屋のみそとんかつ 値段の割には結構なボリュームがあります。 アツアツで提供されてくるのも嬉しいですね。 甘めの味噌がとんかつと合っていると思います! 矢場とん 矢場町本店 わらじとんかつ 名前のとおり、「わらじ」かと思うくらい大きいとんかつがのっています。 みそだれとソースの二種類がかかっていて2つの味を楽しめます。 ご飯もたっぷりでかなりボリュームのある一品でした。 名代とんかつ かつくら四条東洞院店 とんかつ膳 麦ごはん、お味噌汁、キャベツはおかわり自由なのでお腹いっぱいになります。 名代とんかつ かつくら四条寺町店 とんかつ膳 ちょっと値段は高めですが、麦ごはん、お味噌汁、キャベツはおかわり自由です。 すずや とんかつ茶づけ 鉄板に焼けたしょうゆの匂いと味が、とんかつの衣とキャベツに絡み合って食欲をそそります。 とんかつ 江戸家 とんかつ お肉が柔らかくてジューシー。サクサクの衣をまとった揚げたてのとんかつは、ごはんにピッタリ。ごはんやお味噌汁もとっても美味しいです。 沢内甚句 とんかつ 昼の飛び込み、おいしいトンカツでした。店も混んでいたし、どうなるかなと思いましたが、肉厚、かみごたえ、ジューシー加減良かったですね。 とんかつ和幸 エクセル水戸店 とんかつ弁当あやめ 一口サイズのひれかつと海老フライ、メンチかつが入った盛合せ弁当。 ---- 50件出力しました。

発生している実行結果

出力なし

アンサーを参考にしたソース

#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import requests import urllib import json import re #正規表現で特定のワードを検索 menu_name = "とんかつ" def gnavi_api(): keyid = "" url = "https://api.gnavi.co.jp/PhotoSearchAPI/20150630/" #input("メニュー名を入力してください:") encoding = 'utf-8' query = [ ("format", "json"), ("keyid", keyid), ("menu_name", menu_name.encode(encoding)), ("hit_per_page", 50), # default:15, max:50 ("offset", 1), # 検索開始位置(デフォルト:1) ] # Generate URL. url += "?{0}".format(urllib.parse.urlencode(query)) # Execute API try: result = urllib.request.urlopen(url).read() return result except: raise Exception("APIアクセスに失敗しました。") def parse_json(json_f): # parse json parsed_json = json.loads(json_f) # Check error. if 'error' in parsed_json: if 'message' in parsed_json: raise Exception('{0}'.format(parsed_json['message'])) else: raise Exception('データ取得に失敗しました') # Save json. with open('output.json', 'w') as f: json.dump(parsed_json, f) # 該当件数 total_hit_count = parsed_json['response'].get('total_hit_count', 0) # 1回のリクエストで得る最大投稿件数(デフォルト:15、上限:50) hit_per_page = parsed_json['response'].get('hit_per_page', 0) # ヒット件数が0以下なら終了 if total_hit_count <= 0 or hit_per_page <= 0: raise Exception("指定した内容ではヒットしませんでした。") # ヒット件数表示 print("{0}件ヒットしました。".format(min(total_hit_count, hit_per_page))) input_num = int(input("追加で取得するコメントの文章数を入力してください: ")) f = open('answer.txt', 'w') # 応援口コミデータ取得 for (_, seq) in enumerate(parsed_json['response']): line = [] try: photo = parsed_json["response"]["{0}".format(seq)]["photo"] except: continue # コメント if(photo.get('comment', None)): userComment = photo.get('comment') removeCharacters = str.maketrans({ '\r': '', '\n': '', '\t': '' }) userComment = userComment.translate(removeCharacters) commentLines = re.split('。|!|♪', userComment) #とりあえず'。'と'!'で分割 line = [] REPEAT = 3 for i, commentLine in enumerate(commentLines): if menu_name in commentLine: line.append([commentLine]) offset = 1 while True: # マイナスのindexにならないようにする if i - offset >= 0: tmp = commentLines[i-offset] else: tmp = "" line[-1].append(tmp) # kwが含まれたら探索を終了する終了条件 if (any(menu_name in t for t in result[-1][1:]) and (offset >= REPEAT) ): break # プラス側のインデックスは例外処理で対処 try: tmp = commentLines[i+offset] except IndexError: tmp = "" line[-1].append(tmp) # kwが含まれたら探索を終了する終了条件 if (any(menu_name in t for t in result[-1][1:]) and (offset >= REPEAT) ): break # 終了条件 if offset == REPEAT: break offset += 1 #改行区切りで出力 f.write("\n".join(line)) f.close() def main(): try: result = gnavi_api() parse_json(result) except Exception as e: print(e) if __name__ == '__main__': sys.exit(main())

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

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

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

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

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

guest

回答1

0

ベストアンサー

質問

(0,0)にとんかつと含まれる文章。(0,1)にその文章をiとしたらi-1の文章。(0,2)にi+1,(0,3)にi-2...というように入れていきたいです。

  • 右側と左側どちらか先に見つかったら、探索を終了して次のとんかつに移動ですか?それとも右側だけですか?
  • 文章の端ではとんかつが見つからなくなる場合がありますが、その場合の終了条件はどうしますか?

Python

1# テストデータ 2samples = [ 3 "とんかつ1", 4 "とんかつ2", 5 "a", 6 "b", 7 "c", 8 "d", 9 "e", 10 "f", 11 "g", 12 "h", 13 "i", 14 "j", 15 "k", 16 "l", 17 "とんかつ3", 18] 19 20# 抽出コード 21result = [] 22kw = "とんかつ" 23MAX_REPEAT = 5 24MIN_REPEAT = 2 25for i, sample in enumerate(samples): 26 if kw in sample: 27 result.append([sample]) 28 29 offset = 1 30 while True: 31 # マイナスのindexにならないようにする 32 if i - offset >= 0: 33 tmp = samples[i-offset] 34 else: 35 tmp = "" 36 result[-1].append(tmp) 37 38 # kwが含まれたら探索を終了する終了条件 39 if (any(kw in t for t in result[-1][1:]) 40 and (offset >= MIN_REPEAT) 41 ): 42 break 43 44 # プラス側のインデックスは例外処理で対処 45 try: 46 tmp = samples[i+offset] 47 except IndexError: 48 tmp = "" 49 result[-1].append(tmp) 50 51 # kwが含まれたら探索を終了する終了条件 52 if (any(kw in t for t in result[-1][1:]) 53 and (offset >= MIN_REPEAT) 54 ): 55 break 56 57 # 終了条件 58 if offset == MAX_REPEAT: 59 break 60 61 offset += 1 62 63result 64# [['とんかつ1', '', 'とんかつ2', ''], 65# ['とんかつ2', 'とんかつ1', 'a', ''], 66# ['とんかつ3', 'l', '', 'k', '', 'j', '', 'i', '', 'h', '']]

投稿2018/08/07 23:44

編集2018/08/08 05:48
tachikoma

総合スコア3601

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

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

rrrrrrrry

2018/08/07 23:47

input_numで追加する文章数を入力するようにしています。つまりjに2と入力されたら(x,4)までは最低でも出力するようにしたいです。
tachikoma

2018/08/08 00:05

文章が2以上続かない場合、つまり最初の文章でとんかつが表れた場合、左側の探索ができませんが、その場合はNoneなどを入れて右側だけ追加する、という形にしますか?
rrrrrrrry

2018/08/08 01:22

空文字NULLを入れて処理します。 とんかつは美味しい。大きい。なら (0,0)にとんかつは美味しい(0,1)にNULL(0,2)に大きいのようにしたいです。
rrrrrrrry

2018/08/08 04:48

わかりづらいでしょうか?
rrrrrrrry

2018/08/08 06:40

ベストアンサーにさせていただきました。ありがとうございます。 参考にさせていただき、プログラムを編集しているのですが、自分の入力だとうまく回りません。 もう少し試行してみますが、自分が提示しているプログラムで置き換えできますでしょうか?
tachikoma

2018/08/08 07:06

どう動かないかを具体的に教えてもらえると何かしらコメントは出来ると思います。
rrrrrrrry

2018/08/08 12:48

Max(min)_repeatの意味を教えてください。
rrrrrrrry

2018/08/08 14:19

一応参考に組みましたが全くデータが出力されなくなってしまいました。一度見ていただけますか?質問の方に書き換えたソースを貼ります。
tachikoma

2018/08/09 00:31

Max(min)_repeatは最大(最小)の探索回数です。最大探索回数はとなりのkwが見つからない場合の打ち切り回数です。最小は例えばすぐとなりにkwが現れたとしても、MIN_REPEATまで探索を繰り返すための数字です。
tachikoma

2018/08/09 00:32 編集

commentLinesもしくはそれをリスト化したものlist(commentLines)がどんな状態になってますか?
rrrrrrrry

2018/08/09 01:03

処理の部分でのエラーは無くなりました。 ファイル書き込みの部分がうまくいかないのですがjoinは使わないほうがいいのでしょうか?
tachikoma

2018/08/09 01:42

lineはリストのリストになっているので、そのままではjoinは使えません。f.write("\n".join(line[0]))なら通ると思います。
rrrrrrrry

2018/08/09 01:46

list index out of rangeと出力され、結果は0byteになってしまいました。
tachikoma

2018/08/09 02:21

lineが空になっていますね。今の状況だと抽出プロセスでコケています。デバグ頑張ってください。
rrrrrrrry

2018/09/10 07:13

時間差での質問申し訳ございません。 if (any(kw in t for t in result[-1][1:]) の意味を教えていただけますでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問