こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

TwitterAPIでの検索の組み合わせ

唐突に質問失礼致します。

TwitterAPIを用いて指定の文字列を抽出しようとしています。

具体的には
ユーザー名(name)に「病院」という単語を含み
かつ
ツイートに「治療」という単語を含む
ような形です。

スクリーンネームではなく、ネーム(ユーザー名)で拾いたいです。

※スクリーンネームとネーム(ユーザー名)の違い
screen_name(@~以降の英数字の名前 例:@aaaなど)
name(プロフィールで変更可能なユーザー名 例:鈴木太郎など)

例えば、
from演算子を使って「治療 from:xxxxx」で検索すると、アカウントのスクリーンネームが「@xxxxx」からのツイートの中で「治療」が含まれる検索結果が表示されます。

しかし、このようにスクリーンネーム(screen_name)ではなく
プロフィールのユーザー名(name)にして複数検索したいです。

例えば、PHPで
「治療あるいは予防(または両方含む)」という2つの単語を含むツイートをした、「病院」という単語を含むユーザー名(name)を抽出したい場合、

$key = "治療 OR 予防 from:●●●";

などで●●●の部分をどう記述すればいいでしょうか?

['name']と書き入れたりすればいいのでしょうか?

どう検索コマンドを組み合わせて記述すればいいか困っています。

(参考)
Twitter検索オプションと高度な検索
http://www.e-letter.jp/sns/twitter/index38.html


教えていただけたら幸いに存じ上げます。

投稿日時 - 2014-09-23 10:52:21

QNo.8764986

すぐに回答ほしいです

質問者が選んだベストアンサー

えーっと

>> $key = "治療";
>> $options = array('q'=>$key,'count'=>'1','lang'=>'ja');
>> $url = 'https://api.twitter.com/1.1/search/tweets.json?exclude_replies=true';
>> $json = $twObj->OAuthRequest($url,'GET',$options);
>> $jset = json_decode($json, true);

これはよく http://qiita.com/rana_kualu/items/357a031c0453a3538ad3 みたいな感じでダメだと言われる不恰好な書き方なので以下のように書きましょう。include_entitiesもデフォルトでtrueなので書く必要性ゼロです。

<?php

// ライブラリの読み込み
require 'twitteroauth.php';

// TwitterOAuthオブジェクトの生成
$to = new TwitterOAuth('***', '***', '***', '***');

// パラメータの設定
$params = array('q'=>'治療','count'=>'1','lang'=>'ja');

// データを取得、これは自動でjson_decodeされる
// 但し第2引数にtrueを渡していないので
// 連想配列ではなくオブジェクトとしてデコードされる
$result = $to->get('search/tweets', $params);

// エラーチェックは是非書いておきましょう
if (!isset($result->statuses)) {
 // ここでは簡易的にテキストだけ出してdieしていますが、実際にWebサービスとして
 // 公開する際はちゃんとエラー時にもHTMLを出力したほうがいいです
 die(isset($result->errors[0]->message) ? $result->errors[0]->message : '不明なエラー');
}

// 絞り込む
$statuses = array_filter($result->statuses, function ($status) {
 return
  strpos($status->user->name, '病院') &&
  strpos($status->text, '治療')
 ;
});

// テスト表示してみる
foreach ($statuses as $status) {
 echo htmlspecialchars($status->text, ENT_QUOTES, 'UTF-8', false) . '<br>' . PHP_EOL;
}

投稿日時 - 2014-09-24 08:55:44

お礼

丁寧な回答、本当にありがとうございます!

なかなかうまく動作しないので1ヶ月試行錯誤中ですが、参考にしながら頑張って作りたいと思います。

お礼が遅れて恐縮でしたが、一度ベストアンサーで締め切らせて頂きます。

心より御礼申し上げます。

投稿日時 - 2014-10-20 19:07:56

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

以下は蛇足です。

回答No.2のようにエラーチェックは事実上TwitterAPIを利用する上では必須になってきます。毎回これを書くのはちょっとつらいので、もしこの部分をラクにやりたいとお考えならば、ぜひ私の自作したライブラリを使ってみてください。twitteroauthが非常に古くてあまり洗練されていないことに業を煮やして作ってしまったやつですw

GitHub - TwistOAuth
https://github.com/mpyw/TwistOAuth

twitteroauthとの互換性を考えて作っているので、使い方は非常に似ています。既に提示したサンプルコードをこのライブラリ用に書き直すと以下のようになります。なお、このライブラリはtwitteroauthのようにOAuth.phpを必要としません。このファイル単独で利用可能です。また、PHP5.4以降では array() は [] と簡略化して書くことが出来るので、ここではその表記を使用することにします。

<?php

require 'TwistOAuth.php';

try {

 $to = new TwistOAuth('***', '***', '***', '***');
 $params = ['q' => '治療' ,'count' => '1', 'lang'=>'ja'];
 $statuses = $to->get('search/tweets', $params)->statuses;
 $statuses = array_filter($result->statuses, function ($status) {
  return
   strpos($status->user->name, '病院') &&
   strpos($status->text, '治療')
  ;
 });
 foreach ($statuses as $status) {
  echo htmlspecialchars($status->text, ENT_QUOTES, 'UTF-8', false) . '<br>' . PHP_EOL;
 }

} catch (TwistException $e) {
 
 echo $e->getMessage();
 
}

このライブラリでは、エラーが発生しときにはTwistException例外オブジェクトがスローされるようになっています。それをcatchして処理するだけでいいので、issetでチェックする必要がありません。ゆえに以下のように「->」でつなげて書けてしまうのもメリットの一つですね。

$statuses = $to->get('search/tweets', $params)->statuses;

なお、前の回答でも今回の回答でも出力時にhtmlspecialcharsを通していますが、第4引数にfalseを渡していることに着目してください。これはTwitterのエスケープの仕様が不十分なことによるものです。詳しくは以下の説明を読んでください。

https://github.com/mpyw/TwistOAuth#tweets-are-already-escaped-wtf
http://php.net/manual/ja/function.htmlspecialchars.php

投稿日時 - 2014-09-24 09:10:32

ANo.1

> ユーザー名(name)に「病院」という単語を含み
> かつ
> ツイートに「治療」という単語を含む

出来ません。ユーザ名のみを対象とするクエリは作成できません。

やるとすれば普通に「病院 治療」で検索して、取得データを

$statuses = array_filter($statuses, function ($status) {
 return
  strpos($status->user->name, '病院') &&
  strpos($status->text, '治療')
 ;
});

で絞り込む程度ですね。

投稿日時 - 2014-09-23 17:17:01

補足

回答ありがとうございます!

そうですか・・・。fromではユーザ名のみを検索はできないのですね…。

仰った通り
$statuses = array_filter($statuses, function ($status) {
 return
  strpos($status->user->name, '病院') &&
  strpos($status->text, '治療')
 ;
});
で検索してみます。


そのままだと

$statuses = array_filter($statuses, function ($status) の行に
Notice: Undefined variable: statuses in xxxx.php on line xx

strpos($status->user->name, '病院') &&の行に
Warning: array_filter() expects parameter 1 to be array, null given in xxxx.php on line xx


が出たので取得データを読み込ませる必要があるのですね…。

実は今現在、

$key = "治療";
$options = array('q'=>$key,'count'=>'1','lang'=>'ja');
$url = 'https://api.twitter.com/1.1/search/tweets.json?exclude_replies=true';
$json = $twObj->OAuthRequest($url,'GET',$options);
$jset = json_decode($json, true);


//※$twObjは前にカスタマーキーなど定義済み(動作確認済)


・・でツイート内に「治療」を含むデータが抽出できました。

しかしユーザ名(スクリーンネーム)が「病院」のものを拾い出すのにどこに差し込めばいいのか迷っています。


この場合、
jset2 = strpos($jset->user->name, '病院');
のような形でどこかに挿入するのでしょうか・・・?(最後につけても動作しませんでした)


あるいは$statuses = array_filter($・・の形で書き直すとどういう形になるのでしょうか・・?

初心者的な質問で申し訳ございません。

試行錯誤してみたのですがどうしても分からず暗礁に乗り上げています。

引き続いて恐縮ですが、もし差し当たりなければ教えていただけたら幸いに存じ上げます。

投稿日時 - 2014-09-24 06:14:21

あなたにオススメの質問