回答編集履歴
10
修正
answer
CHANGED
@@ -123,15 +123,15 @@
|
|
123
123
|
> ・convert_url(url)の引数urlはreturnされた「"https://drive.google.com/uc?export=view&id=%s" % a.group(1)」の値が記載されている認識でよろしいでしょうか。
|
124
124
|
|
125
125
|
yesかnoかでいえばnoです。
|
126
|
-
convert_url(url)の引数urlには、
|
126
|
+
convert_url(url)の引数urlには、tweetcontent.json内に記載されている、googleドライブ上のファイルへのパス(img_url)が渡されます。
|
127
127
|
|
128
128
|
|
129
129
|
|
130
130
|
> 認識が間違っている場合、引数にはどの値(ファイルパス指定、JSONに記載したファイルパスの変数を指定など)を定義するべきでしょうか。
|
131
131
|
|
132
|
-
convert_url(url)の引数urlには、
|
132
|
+
convert_url(url)の引数urlには、tweetcontent.jsonに記載されている、googleドライブ上のファイルへのパスを渡すべきです。
|
133
133
|
|
134
|
-
|
134
|
+
回答のコードは「tweetcontent.jsonに記載されたgoogleドライブ上のファイルへのパス」をconvert_url関数に渡すようにしています。
|
135
135
|
|
136
136
|
|
137
137
|
|
9
修正
answer
CHANGED
@@ -129,9 +129,9 @@
|
|
129
129
|
|
130
130
|
> 認識が間違っている場合、引数にはどの値(ファイルパス指定、JSONに記載したファイルパスの変数を指定など)を定義するべきでしょうか。
|
131
131
|
|
132
|
-
convert_url(url)の引数urlには、JSONに記載されている、googleドライブ上のファイルへのパス
|
132
|
+
convert_url(url)の引数urlには、JSONに記載されている、googleドライブ上のファイルへのパスを渡すべきです。
|
133
133
|
|
134
|
-
なお、回答のコードは
|
134
|
+
なお、回答のコードは「JSONに記載されたgoogleドライブへのパス」をconvert_url関数に渡すようにしています。
|
135
135
|
|
136
136
|
|
137
137
|
|
8
修正
answer
CHANGED
@@ -129,8 +129,9 @@
|
|
129
129
|
|
130
130
|
> 認識が間違っている場合、引数にはどの値(ファイルパス指定、JSONに記載したファイルパスの変数を指定など)を定義するべきでしょうか。
|
131
131
|
|
132
|
-
引数には、JSONに記載
|
132
|
+
convert_url(url)の引数urlには、JSONに記載されている、googleドライブ上のファイルへのパス「JSONに記載したファイルパス」を渡すべきです。
|
133
133
|
|
134
|
+
なお、回答のコードは、元質問のコードをなるべく変えないように「JSONに記載されたgoogleドライブへのパス」をconvert_url関数に渡すようにしています。
|
134
135
|
|
135
136
|
|
136
137
|
|
7
修正
answer
CHANGED
@@ -208,7 +208,7 @@
|
|
208
208
|
|
209
209
|
# mainという名前の関数は存在する必要はない
|
210
210
|
def add(a,b):
|
211
|
-
print("
|
211
|
+
print("add関数を呼び出しました")
|
212
212
|
return a + b
|
213
213
|
|
214
214
|
|
@@ -225,7 +225,7 @@
|
|
225
225
|
return a - b
|
226
226
|
|
227
227
|
def add(a,b):
|
228
|
-
print("
|
228
|
+
print("add関数を呼び出しました")
|
229
229
|
return a + b
|
230
230
|
|
231
231
|
# 関数定義以外で一番最初に現れる行なので、ここから実行される。
|
@@ -234,6 +234,6 @@
|
|
234
234
|
|
235
235
|
# ここより下は上の2行が実行された後評価され、実行される。
|
236
236
|
if __name__ == '__main__':
|
237
|
-
print('実行:__name__==__main__')
|
237
|
+
print('実行: IF __name__ = =__main__:')
|
238
238
|
|
239
239
|
```
|
6
修正
answer
CHANGED
@@ -123,7 +123,7 @@
|
|
123
123
|
> ・convert_url(url)の引数urlはreturnされた「"https://drive.google.com/uc?export=view&id=%s" % a.group(1)」の値が記載されている認識でよろしいでしょうか。
|
124
124
|
|
125
125
|
yesかnoかでいえばnoです。
|
126
|
-
convert_url(url)の引数urlは、JSONに記載
|
126
|
+
convert_url(url)の引数urlには、JSONに記載されている、googleドライブ上のファイルへのパス(img_url)が渡されます。
|
127
127
|
|
128
128
|
|
129
129
|
|
5
修正
answer
CHANGED
@@ -137,24 +137,26 @@
|
|
137
137
|
> ・main()関数にはconvert_url(url)を呼び出す関数がないようですが、こちらの関数はどのように呼び出せばよろしいでしょうか。
|
138
138
|
|
139
139
|
コメントを追加しました。
|
140
|
-
回答コード全文には最初から、upload_media関数内に
|
140
|
+
回答コード全文には最初から、upload_media関数内にconvert_url(url)を呼び出すコードを入れておりましたが、
|
141
141
|
「# <----追加」というコメントを入れ忘れておりました。
|
142
142
|
|
143
|
+
main()からconvert_url(url)を呼ぶのではなく、
|
143
|
-
upload_media関数
|
144
|
+
upload_media関数の中からconvert_url(url)を呼び出しています。
|
144
145
|
|
145
146
|
|
146
147
|
|
148
|
+
|
147
149
|
> ・main()関数に記載したjson_file_pathにjsonファイルのパスを直指定しているのですが、こちらはjsonファイル名を記載するのが正しいのでしょうか。
|
148
150
|
|
149
151
|
回答コードは、自分のテスト環境用のjsonファイルパスを記載してしまっていたので、元質問のファイルパスに修正しました。
|
150
|
-
元質問のコードのように、jsonファイルのパスを直指定で問題ありません。
|
152
|
+
元質問のコードのように、jsonファイルのパスを直指定するやり方で問題ありません。
|
151
153
|
|
152
154
|
|
153
155
|
> ・Pythonの実行方法として、定義された関数をmainから実行していくという認識であっているのでしょうか。※初歩的な質問で申し訳ございません
|
154
156
|
|
155
157
|
特にmainから実行していくという制約はありません。
|
156
158
|
|
157
|
-
importを無視しての話になりますが
|
159
|
+
(importを無視しての話になりますが)pythonでは上から順番に読み取られ、実行できる部分があれば上から実行されます。
|
158
160
|
ただし、関数定義部分(def)やクラス定義部分(class)等は、読み取られるだけで実行されません。
|
159
161
|
(※importを読み取ったときの挙動等、細かい点まで考慮すると上記の説明は完全に正確というわけではありませんが、雰囲気としてそういうものだと考えてくだされば結構です)
|
160
162
|
|
4
追加
answer
CHANGED
@@ -110,11 +110,128 @@
|
|
110
110
|
|
111
111
|
|
112
112
|
def main():
|
113
|
-
json_file_path = '
|
113
|
+
json_file_path = '/content/sample_data/tweetcontent.json' # ファイルパスを修正しました。
|
114
114
|
tweet_content = get_tweet_content(json_file_path)
|
115
115
|
media_id = upload_media(tweet_content['img_url'])
|
116
116
|
post_tweet(tweet_content['tweet_text'], media_id)
|
117
117
|
|
118
118
|
if __name__ == '__main__':
|
119
119
|
main()
|
120
|
+
```
|
121
|
+
|
122
|
+
|
123
|
+
> ・convert_url(url)の引数urlはreturnされた「"https://drive.google.com/uc?export=view&id=%s" % a.group(1)」の値が記載されている認識でよろしいでしょうか。
|
124
|
+
|
125
|
+
yesかnoかでいえばnoです。
|
126
|
+
convert_url(url)の引数urlは、JSONに記載したgoogleドライブへのパス(url)が渡されます。
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
> 認識が間違っている場合、引数にはどの値(ファイルパス指定、JSONに記載したファイルパスの変数を指定など)を定義するべきでしょうか。
|
131
|
+
|
132
|
+
引数には、JSONに記載したgoogleドライブへのパス(url)が渡されていればよいので、元質問のコードから変える必要はありません。
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
> ・main()関数にはconvert_url(url)を呼び出す関数がないようですが、こちらの関数はどのように呼び出せばよろしいでしょうか。
|
138
|
+
|
139
|
+
コメントを追加しました。
|
140
|
+
回答コード全文には最初から、upload_media関数内に、convert_url(url)を呼び出すコードを入れておりましたが、
|
141
|
+
「# <----追加」というコメントを入れ忘れておりました。
|
142
|
+
|
143
|
+
upload_media関数内に、convert_url(url)を呼び出していますので、main()で呼ぶ必要はありません。
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
> ・main()関数に記載したjson_file_pathにjsonファイルのパスを直指定しているのですが、こちらはjsonファイル名を記載するのが正しいのでしょうか。
|
148
|
+
|
149
|
+
回答コードは、自分のテスト環境用のjsonファイルパスを記載してしまっていたので、元質問のファイルパスに修正しました。
|
150
|
+
元質問のコードのように、jsonファイルのパスを直指定で問題ありません。
|
151
|
+
|
152
|
+
|
153
|
+
> ・Pythonの実行方法として、定義された関数をmainから実行していくという認識であっているのでしょうか。※初歩的な質問で申し訳ございません
|
154
|
+
|
155
|
+
特にmainから実行していくという制約はありません。
|
156
|
+
|
157
|
+
importを無視しての話になりますが、pythonでは上から順番に読み取られ、実行できる部分があれば上から実行されます。
|
158
|
+
ただし、関数定義部分(def)やクラス定義部分(class)等は、読み取られるだけで実行されません。
|
159
|
+
(※importを読み取ったときの挙動等、細かい点まで考慮すると上記の説明は完全に正確というわけではありませんが、雰囲気としてそういうものだと考えてくだされば結構です)
|
160
|
+
|
161
|
+
例:
|
162
|
+
|
163
|
+
[1]
|
164
|
+
|
165
|
+
```
|
166
|
+
def sub(a,b):
|
167
|
+
print("sub関数を呼び出しました")
|
168
|
+
return a - b
|
169
|
+
|
170
|
+
def main(a,b):
|
171
|
+
print("main関数を呼び出しました")
|
172
|
+
return a + b
|
173
|
+
|
174
|
+
# 関数等定義以外で一番最初に現れる行なので、ここから実行される。
|
175
|
+
if __name__ == '__main__':
|
176
|
+
# main()が最初でなくてよい
|
177
|
+
print(sub(1,2))
|
178
|
+
print(main(1,2))
|
179
|
+
|
180
|
+
```
|
181
|
+
|
182
|
+
[2]
|
183
|
+
|
184
|
+
```
|
185
|
+
def sub(a,b):
|
186
|
+
print("sub関数を呼び出しました")
|
187
|
+
return a - b
|
188
|
+
|
189
|
+
def main(a,b):
|
190
|
+
print("main関数を呼び出しました")
|
191
|
+
return a + b
|
192
|
+
|
193
|
+
# if __name__ == '__main__':がなくても
|
194
|
+
# 関数定義以外で一番最初に現れる行なので、ここから実行される。
|
195
|
+
print(sub(1,2))
|
196
|
+
print(main(1,2))
|
197
|
+
|
198
|
+
```
|
199
|
+
|
200
|
+
[3]
|
201
|
+
|
202
|
+
```
|
203
|
+
def sub(a,b):
|
204
|
+
print("sub関数を呼び出しました")
|
205
|
+
return a - b
|
206
|
+
|
207
|
+
# mainという名前の関数は存在する必要はない
|
208
|
+
def add(a,b):
|
209
|
+
print("main関数を呼び出しました")
|
210
|
+
return a + b
|
211
|
+
|
212
|
+
|
213
|
+
if __name__ == '__main__':
|
214
|
+
print(sub(1,2))
|
215
|
+
print(add(1,2))
|
216
|
+
```
|
217
|
+
|
218
|
+
[4]
|
219
|
+
|
220
|
+
```
|
221
|
+
def sub(a,b):
|
222
|
+
print("sub関数を呼び出しました")
|
223
|
+
return a - b
|
224
|
+
|
225
|
+
def add(a,b):
|
226
|
+
print("main関数を呼び出しました")
|
227
|
+
return a + b
|
228
|
+
|
229
|
+
# 関数定義以外で一番最初に現れる行なので、ここから実行される。
|
230
|
+
print(sub(1,2))
|
231
|
+
print(add(1,2))
|
232
|
+
|
233
|
+
# ここより下は上の2行が実行された後評価され、実行される。
|
234
|
+
if __name__ == '__main__':
|
235
|
+
print('実行:__name__==__main__')
|
236
|
+
|
120
237
|
```
|
3
追加
answer
CHANGED
@@ -34,7 +34,7 @@
|
|
34
34
|
|
35
35
|
```
|
36
36
|
import json
|
37
|
-
import random
|
37
|
+
import random # <-------回答追加時当初から追加しています
|
38
38
|
import re # <-------追加
|
39
39
|
from requests_oauthlib import OAuth1Session
|
40
40
|
#urlを使用するためのモジュール
|
@@ -84,8 +84,8 @@
|
|
84
84
|
#画像をTwitterにアップロードし、media_idをリターン
|
85
85
|
#img_urlはJSONで指定した画像オブジェクト
|
86
86
|
def upload_media(img_url): #===========================
|
87
|
-
# urlを変換する
|
87
|
+
# urlを変換する # <-------回答追加時当初から追加しています
|
88
|
-
img_url = convert_url(img_url)
|
88
|
+
img_url = convert_url(img_url) # <-------回答追加時当初から追加しています
|
89
89
|
#urlをオープンする
|
90
90
|
res = urllib.request.urlopen(img_url) #=========================
|
91
91
|
img_data = res.read()
|
2
コメントを追加
answer
CHANGED
@@ -85,7 +85,7 @@
|
|
85
85
|
#img_urlはJSONで指定した画像オブジェクト
|
86
86
|
def upload_media(img_url): #===========================
|
87
87
|
# urlを変換する
|
88
|
-
img_url = convert_url(img_url)
|
88
|
+
img_url = convert_url(img_url) # <-------追加
|
89
89
|
#urlをオープンする
|
90
90
|
res = urllib.request.urlopen(img_url) #=========================
|
91
91
|
img_data = res.read()
|
1
追記
answer
CHANGED
@@ -1,3 +1,120 @@
|
|
1
1
|
random モジュールがないというエラーメッセージなので、冒頭で
|
2
2
|
import random
|
3
|
-
とすればよいのではないでしょうか。
|
3
|
+
とすればよいのではないでしょうか。
|
4
|
+
|
5
|
+
------------
|
6
|
+
追記
|
7
|
+
|
8
|
+
まず、上記のコードで正常に動かないところを修正します。
|
9
|
+
具体的には、
|
10
|
+
```
|
11
|
+
def upload__media(img_url):
|
12
|
+
```
|
13
|
+
を
|
14
|
+
```
|
15
|
+
def upload_media(img_url):
|
16
|
+
```
|
17
|
+
に変えます。(uploadとdataの間のアンダーバーを2つから1つに変える。)
|
18
|
+
|
19
|
+
その上で、/content/sample_data/tweetcontent.json の中の "img_url":の「対象ファイルのURL」を、
|
20
|
+
ネット上の自由に使用可能な素材へのリンクに変えてテストしたところ、
|
21
|
+
自分の環境では正常に画像ツイートできました。
|
22
|
+
|
23
|
+
ためしに「対象ファイルのURL」を自分のGoogle Drive上の画像ファイルへのリンクに変えたところ、
|
24
|
+
質問者さんと同じ
|
25
|
+
Image upload failed: %s {"request":"/1.1/media/upload.json","error":"media type unrecognized."}
|
26
|
+
|
27
|
+
というエラーが出ました。
|
28
|
+
|
29
|
+
したがって、Google Driveの「リンクの取得」で取得したリンクそのままでは、twitter APIからは画像データを正常に取得できないと推測されます。
|
30
|
+
|
31
|
+
そこで下のコードでは、[stackoverrun](https://stackoverflow.com/questions/10311092/displaying-files-e-g-images-stored-in-google-drive-on-a-website) の内容を参考に、urlを取得できる形に変換する関数(convert_url)を追加しています。
|
32
|
+
|
33
|
+
全文
|
34
|
+
|
35
|
+
```
|
36
|
+
import json
|
37
|
+
import random
|
38
|
+
import re # <-------追加
|
39
|
+
from requests_oauthlib import OAuth1Session
|
40
|
+
#urlを使用するためのモジュール
|
41
|
+
import urllib.request
|
42
|
+
|
43
|
+
# url変換に使用する正規表現
|
44
|
+
pattern = re.compile(r".*/file/./(.*)/.*") # <-------追加
|
45
|
+
|
46
|
+
#下記TwitterのAPIキー、アクセスキーのため記載しておりません
|
47
|
+
CONSUMER_KEY = '****************************'
|
48
|
+
CONSUMER_SECRET = '****************************'
|
49
|
+
ACCESS_TOKEN = '****************************'
|
50
|
+
ACCESS_TOKEN_SECRET = '****************************'
|
51
|
+
|
52
|
+
#Twitterアクセスキーを変数へ格納
|
53
|
+
twitter = OAuth1Session(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_TOKEN,ACCESS_TOKEN_SECRET)
|
54
|
+
|
55
|
+
#メディアアップロードに使用するURL
|
56
|
+
url_media = "https://upload.twitter.com/1.1/media/upload.json"
|
57
|
+
|
58
|
+
#テキストアップロードに使用するURL
|
59
|
+
url_text = "https://api.twitter.com/1.1/statuses/update.json"
|
60
|
+
|
61
|
+
|
62
|
+
# Googleドライブ上のリンクを、twitter API等で直接取得できるurlに変換する関数 <-------追加
|
63
|
+
def convert_url(url):
|
64
|
+
a = re.search(pattern, url)
|
65
|
+
try:
|
66
|
+
return "https://drive.google.com/uc?export=view&id=%s" % a.group(1)
|
67
|
+
except (AttributeError, IndexError) as e:
|
68
|
+
# パターンマッチしない場合はメッセージを出して、渡されたurlをそのまま返す。
|
69
|
+
print("[%s]はパターンにマッチしないため、そのまま返します。" % url)
|
70
|
+
return url
|
71
|
+
|
72
|
+
|
73
|
+
#jsonファイルからツイート本文と画像urlを取得
|
74
|
+
def get_tweet_content(json_file_path):
|
75
|
+
#テキストファイルを読み込む
|
76
|
+
file = open(json_file_path, 'r', encoding='utf-8')
|
77
|
+
#開いたファイルをjson.load関数でJSONとして読み込む
|
78
|
+
json_data = json.load(file)
|
79
|
+
#JSONとして読み込んだfile変数が格納されたjson_data変数に、jsonデータを格納
|
80
|
+
#random.choice()でリストからランダムに要素を一つ取得
|
81
|
+
return random.choice(json_data["contents"])
|
82
|
+
|
83
|
+
|
84
|
+
#画像をTwitterにアップロードし、media_idをリターン
|
85
|
+
#img_urlはJSONで指定した画像オブジェクト
|
86
|
+
def upload_media(img_url): #===========================
|
87
|
+
# urlを変換する
|
88
|
+
img_url = convert_url(img_url)
|
89
|
+
#urlをオープンする
|
90
|
+
res = urllib.request.urlopen(img_url) #=========================
|
91
|
+
img_data = res.read()
|
92
|
+
img_files = {'media': img_data}
|
93
|
+
res_media = twitter.post(url_media, files=img_files)
|
94
|
+
|
95
|
+
if res_media.status_code == 200:
|
96
|
+
return json.loads(res_media.text)['media_id']
|
97
|
+
else:
|
98
|
+
print('Image upload failed: %s', res_media.text)
|
99
|
+
exit()
|
100
|
+
|
101
|
+
|
102
|
+
#ツイート本文とアップロード済みの画像のmedia_idを引数にツイート
|
103
|
+
def post_tweet(tweet_text, media_id):
|
104
|
+
params = {'status': tweet_text, 'media_ids': media_id}
|
105
|
+
res = twitter.post(url_text, params=params)
|
106
|
+
if res.status_code == 200:
|
107
|
+
print('Auto Tweet Succeeded.')
|
108
|
+
else:
|
109
|
+
print('Failed. : %d' % res.status_code)
|
110
|
+
|
111
|
+
|
112
|
+
def main():
|
113
|
+
json_file_path = 'contents.json'
|
114
|
+
tweet_content = get_tweet_content(json_file_path)
|
115
|
+
media_id = upload_media(tweet_content['img_url'])
|
116
|
+
post_tweet(tweet_content['tweet_text'], media_id)
|
117
|
+
|
118
|
+
if __name__ == '__main__':
|
119
|
+
main()
|
120
|
+
```
|