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

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

新規登録して質問してみよう
ただいま回答率
85.50%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python

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

Q&A

解決済

2回答

5983閲覧

AttributeError: 'str' object has no attribute 'q'のエラーについて。〜youtube data api〜

jury_new

総合スコア31

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python

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

0グッド

0クリップ

投稿2020/05/12 15:09

前提・実現したいこと

youtubeのapiを使ってどうぶつの森にマッチする動画を収集しようとしております。
youtube data APIのサンプルコードを参考に書いています。
ですが、以下のようなエラーが発生しました。

発生している問題・エラーメッセージ

AttributeError: 'str' object has no attribute 'q'

該当のソースコード

from apiclient.discovery import build from apiclient.errors import HttpError from oauth2client.tools import argparser DEVELOPER_KEY = "取得したAPIキーを入れています" YOUTUBE_API_SERVICE_NAME ="youtube" YOUTUBE_API_VERSION ="v3" def youtube_search(options): youtube = build(YOUTUBE_API_SERVICE_NAME,YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY) search_response = youtube.search().list( q = options.q, part = "id,snippet", maxResults = options.maxresults ).execute() youtube_search('どうぶつの森')

試したこと

AttributeError: 'str' object has no attribute 〜〜〜〜
のように続く他の方のエラーを参考に考えてみたのですが、
なぜエラーが発生しているのかが全くわかりません。
q = options.q,
の部分などqが二回出てくるコードの意味が理解できなかったため、
(サンプルなので合っているはずなんですが)
消して以下のようなコードで実行してみました。
q = options
ですが、今度は別のエラーが発生しました。
ValueError: invalid literal for int() with base 10: 'どうぶつの森'
調べて、INTの引数に10進数で変換不能な値が入っている?と自分なりに解釈しました。
ですが、INTは今回のコードには使用していないためエラーの意味が理解できません。

以前にBeautifulSoupを使って他のサイトをスクレイピングをしていた際のことが
ふと頭に浮かんだのですが、
optionに存在するデータからさらに検索?する時点でoptionのなかにデータが存在しないため検索できず、
エラーをはくといったことと同じニュアンスなのでしょうか?

補足情報(FW/ツールのバージョンなど)

ご教授いただきたい点としましては、

1、q = options.q,のコードでqが二回出てくる意味について
2、今回のエラーを解決する糸口について

です。

よろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

元のサンプルコードと比較して、質問のソースコードで欠落している重要な部分は以下です。(説明に不要な部分は省略しています)

if __name__ == "__main__": argparser.add_argument("--q", help="Search term", default="Google") args = argparser.parse_args() youtube_search(args)

このスクリプトでは、argparseと呼ばれるモジュールについての知識が必要になります。

2行目で

argparser.add_argument("--q" ・・・)

となっています。これは、たとえばスクリプト実行時に

python test.py --q どうぶつの森 --maxresults 10

とすることにより、
args に自動的に「q」と「maxresults」という属性が付与され、
args.qに、指定した文字列(ここでは"どうぶつの森")、および args.maxresultsに指定した数値(ここでは 10)が代入されます。


1、q = options.q,のコードでqが二回出てくる意味について

意味はなく、別々の変数が同じ名前で使われており、わかりにくくなっているだけです。

1番目のqは、youtube.search().list関数で、検索対象文字列を指定するためのパラメータです。
2番目のqは、スクリプト実行時に指定した引数を格納するオブジェクト(args)の属性です。

例えば、わかりやすく置き換えるなら、エントリポイントでは

if __name__ == "__main__": argparser.add_argument("--queryword", help="Search term", default="Google")

とし、youtube_search()関数内で、

q = options.queryword

とします。


(サンプルなので合っているはずなんですが)

消して以下のようなコードで実行してみました。
q = options
ですが、今度は別のエラーが発生しました。
ValueError: invalid literal for int() with base 10: 'どうぶつの森'

(2020/5/13 2:00時点の質問文から引用)

ここは不正確で、q = optionsとしただけでなく、maxresults も下記のように変えましたよね?

maxresults = options

としていなければValueErrorは出ないはずです。仮にmaxResults = options.maxresultsのままならば
AttributeErrorが出るはずです。

ValueErrorが出た原因は、maxresultsに渡すデータは数値でなければいけないのに、options すなわち「'どうぶつの森'という文字列」を渡したからです。


2、今回のエラーを解決する糸口について

今回は、argparseの仕様の理解が鍵だと思います。

エラーを解析する際は思い込みを捨て、前後のコードを丁寧に調べながら紐解いていくことが必要になります。


追記

仮に元の質問のコードを修正する場合は、youtube_search()関数の内部及び呼び出し元を以下のようにすれば動くと思います。

def youtube_search(options): youtube = build(YOUTUBE_API_SERVICE_NAME,YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY) search_response = youtube.search().list( q = options, # 修正 part = "id,snippet", maxResults = 10 # 修正 ).execute() return search_response # 追加 print(youtube_search('どうぶつの森')) # print~ に修正。

投稿2020/05/12 16:53

編集2020/05/13 00:08
patapi

総合スコア651

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

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

jury_new

2020/05/13 02:28

返答ありがとうございます。 1から丁寧に本当にありがとうございます! 大変わかりやすかったです。 モジュールの勉強も進めていきたいと思います。
guest

0

YouTube apiを理解していませんが、optionsは文字列ではなく何らかのクラスが渡されることを想定しているように見えます。
サンプルは本当にこの形ですか?

投稿2020/05/12 15:41

x98000

総合スコア1096

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

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

jury_new

2020/05/13 02:25

返答ありがとうございます。 フィルターなどの深い部分を削減してみました。 その上でサンプルではこのような形になっていました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問