【发布时间】:2015-02-08 22:01:20
【问题描述】:
我正在制作一个应用程序,它使用 Twitter API 接收用户的推文,其中一个组件是从推文文本中提取情绪。对于开发,我使用 xampp,当然使用 Apache HTML Server 作为我的工作区。我正在使用 Eclipse for PHP 作为 IDE。
对于情感提取,我使用的是uClassify Sentiment Classifier。分类器使用 API 接收大量请求,并针对每个请求发回可解析情绪值的 XML 数据。
现在应用程序可以一次处理大量推文(最多允许 3200 条)。例如,如果有 3200 条推文,那么系统将一次向该分类器发送 3200 个 API 调用。不幸的是,对于这个数字,系统无法很好地扩展,实际上 xampp 在使用这些调用运行系统后不久就会崩溃。但是,对于少量的推文(例如 500 条推文),系统运行良好,所以我假设这可能是由于大量 API 调用造成的。请注意,uClassify 每天允许的 API 调用的最大数量为 5000,但由于最大值为 3200,我很确定它不会超过这个数字。
这几乎是我第一次从事这种网络开发工作,所以我不确定我是否在这里犯了一个新手错误。我不确定我可能做错了什么,也不知道从哪里开始寻找。任何建议/见解都会有很大帮助!
编辑:添加有问题的源代码
更新索引方法
function updateIndex($timeline, $connection, $user_handle, $json_index, $most_recent) {
// URL arrays for uClassify API calls
$urls = [ ];
$urls_id = [ ];
// halt if no more new tweets are found
$halt = false;
// set to 1 to skip first tweet after 1st batch
$j = 0;
// count number of new tweets indexed
$count = 0;
while ( (count ( $timeline ) != 1 || $j == 0) && $halt == false ) {
$no_of_tweets_in_batch = 0;
$n = $j;
while ( ($n < count ( $timeline )) && $halt == false ) {
$tweet_id = $timeline [$n]->id_str;
if ($tweet_id > $most_recent) {
$text = $timeline [$n]->text;
$tokens = parseTweet ( $text );
$coord = extractLocation ( $timeline, $n );
addSentimentURL ( $text, $tweet_id, $urls, $urls_id );
$keywords = makeEntry ( $tokens, $tweet_id, $coord, $text );
foreach ( $keywords as $type ) {
$json_index [] = $type;
}
$n ++;
$no_of_tweets_in_batch ++;
} else {
$halt = true;
}
}
if ($halt == false) {
$tweet_id = $timeline [$n - 1]->id_str;
$timeline = $connection->get ( 'statuses/user_timeline', array (
'screen_name' => $user_handle,
'count' => 200,
'max_id' => $tweet_id
) );
// skip 1st tweet after 1st batch
$j = 1;
}
$count += $no_of_tweets_in_batch;
}
$json_index = extractSentiments ( $urls, $urls_id, $json_index );
echo 'Number of tweets indexed: ' . ($count);
return $json_index;
}
情感提取法
function extractSentiments($urls, $urls_id, &$json_index) {
$responses = multiHandle ( $urls );
// add sentiments to all index entries
foreach ( $json_index as $i => $term ) {
$tweet_id = $term ['tweet_id'];
foreach ( $urls_id as $j => $id ) {
if ($tweet_id == $id) {
$sentiment = parseSentiment ( $responses [$j] );
$json_index [$i] ['sentiment'] = $sentiment;
}
}
}
return $json_index;
}
处理多个 API 调用的方法
这是一次处理 uClassify API 调用的地方:
function multiHandle($urls) {
// curl handles
$curls = array ();
// results returned in xml
$xml = array ();
// init multi handle
$mh = curl_multi_init ();
foreach ( $urls as $i => $d ) {
// init curl handle
$curls [$i] = curl_init ();
$url = (is_array ( $d ) && ! empty ( $d ['url'] )) ? $d ['url'] : $d;
// set url to curl handle
curl_setopt ( $curls [$i], CURLOPT_URL, $url );
// on success, return actual result rather than true
curl_setopt ( $curls [$i], CURLOPT_RETURNTRANSFER, 1 );
// add curl handle to multi handle
curl_multi_add_handle ( $mh, $curls [$i] );
}
// execute the handles
$active = null;
do {
curl_multi_exec ( $mh, $active );
} while ( $active > 0 );
// get xml and flush handles
foreach ( $curls as $i => $ch ) {
$xml [$i] = curl_multi_getcontent ( $ch );
curl_multi_remove_handle ( $mh, $ch );
}
// close multi handle
curl_multi_close ( $mh );
return $xml;
}
【问题讨论】:
-
您会收到一个 http 请求进入您的 xampp Web 服务器,即用户名,然后在 PHP 中查找他们的推文,然后仍然在同一个 PHP 脚本中循环浏览这些推文,进行一次调用到每个外部网络服务(uClassify)?如果是这样,发布您的 PHP 脚本可能会很有用(或者,如果它很长,则发布主循环 - 我对您如何执行 Web 服务调用以及如何并行执行它们特别感兴趣。)
-
我正在使用 cURL 来调用 uClassify。我不是每次都为每条推文处理一个调用,而是将一个 curl 句柄添加到一个多句柄(仍在 cURL 中),然后使用 multi_exec()(对于 curl 多句柄)并行处理它们,或者说根据到 libcurl 文档。这使得处理所有这些推文的过程快得多,但它不能很好地扩展到大量推文。我只用大约 300-500 条推文成功地测试了它,它不能在 3200 条推文上正常工作。我已经用代码编辑了帖子。
标签: php api twitter sentiment-analysis