2017-07-10 9 views
0

私はコーディングで非常に新しいので、いくつか問題があります。 Twitterで特定のユーザーのフォロワーのフォロワーのフォロワーを表示したいと思います。これをコード化して深みの限界を設定することができます。しかし、小さなサンプルでコードを実行しているときに、私は同じユーザーに再度遭遇し、私のコードはこれらのユーザーのフォロワーを再表示することがわかりました。これを回避して次のユーザーにスキップできますか?私のコードを実行している間、私は401エラーで発生した、ところで前に表示された同じTwitterユーザーのフォロワーのリストを取得しないようにするには

:あなたは以下の私のコードを見つけることができます。私が作業しているリストにはプライベートユーザがいて、そのユーザが自分のコードをキャッチすると、そのユーザは停止します。さらに、私はこの問題にどのように対処できますか?そのようなユーザーをスキップしてコードを停止させないようにしたいと思います。

ご協力いただきありがとうございます。

PS:私は、私は大規模なサンプルでの作業429エラーに遭遇するだろうことを知っています。これらの問題を修正した後、関連する議論を検討して対処する予定です。

public class mainJava { 
    public static Twitter twitter = buildConfiguration.getTwitter(); 

    public static void main(String[] args) throws Exception { 
     ArrayList<String> rootUserIDs = new ArrayList<String>(); 
     Scanner s = new Scanner(new File("C:\\Users\\ecemb\\Desktop\\rootusers1.txt")); 
     while (s.hasNextLine()) { 
      rootUserIDs.add(s.nextLine()); 
     } 
     s.close(); 

     for (String rootUserID : rootUserIDs) { 
      User rootUser = twitter.showUser(rootUserID); 
      List<User> userList = getFollowers(rootUser, 0); 
     } 
    } 

    public static List<User> getFollowers(User parent, int depth) throws Exception { 
     List<User> userList = new ArrayList<User>(); 
     if (depth == 2) { 
      return userList; 
     } 
     IDs followerIDs = twitter.getFollowersIDs(parent.getScreenName(), -1); 
     long[] ids = followerIDs.getIDs(); 
     for (long id : ids) { 
      twitter4j.User child = twitter.showUser(id); 
      userList.add(child); 
      getFollowers(child, depth + 1); 
      System.out.println(depth + "th user: " + parent.getScreenName() + " Follower: " + child.getScreenName()); 
     } 
     return userList; 
    } 
} 

答えて

0

この特定の問題については、グラフ検索アルゴリズムを実装できると思います。最初にrootユーザーのフォロワーにアクセスする方が良いので、私はBreadth First Searchアルゴリズムを選択しました。アルゴリズムの詳細についてはlinkを参照してください。このコードHashMap<Long, Integer> discoveredUserId

public List<User> getFollowers(User parent, int startDepth, int finalDepth) { 
    List<User> userList = new ArrayList<User>(); 
    Queue<Long> queue = new LinkedList<Long>(); 
    HashMap<Long, Integer> discoveredUserId = new HashMap<Long, Integer>(); 

    try { 
     queue.add(parent.getId()); 
     discoveredUserId.put(parent.getId(), 0); 

     while (!queue.isEmpty()) { 
      long userId = queue.remove(); 
      int discoveredDepth = discoveredUserId.get(userId); 
      if (discoveredDepth == finalDepth) { 
       continue; 
      } 
      User user = twitter.showUser(userId); 
      handleRateLimit(user.getRateLimitStatus()); 
      if (user.isProtected()) { 
       System.out.println(user.getScreenName() + "'s account is protected. Can't access followers."); 
       continue; 
      } 
      IDs followerIDs = null; 
      followerIDs = twitter.getFollowersIDs(user.getScreenName(), -1); 

      handleRateLimit(followerIDs.getRateLimitStatus()); 
      long[] ids = followerIDs.getIDs(); 
      for (int i = 0; i < ids.length; i++) { 
       if (!discoveredUserId.containsKey(ids[i])) { 
        discoveredUserId.put(ids[i], discoveredDepth + 1); 
        User child = twitter.showUser(ids[i]); 
        handleRateLimit(child.getRateLimitStatus()); 
        userList.add(child); 
        if (discoveredDepth >= startDepth && discoveredDepth < finalDepth) { 
         System.out.println(discoveredDepth + ". user: " + user.getScreenName() + " has " + user.getFollowersCount() + " follower(s) " + (i + 1) + ". Follower: " + child.getScreenName()); 
        } 
        queue.add(ids[i]); 
       } else {//prints to console but does not check followers. Just for data consistency 
        User child = twitter.showUser(ids[i]); 
        handleRateLimit(child.getRateLimitStatus()); 
        if (discoveredDepth >= startDepth && discoveredDepth < finalDepth) { 
         System.out.println(discoveredDepth + ". user: " + user.getScreenName() + " has " + user.getFollowersCount() + " follower(s) " + (i + 1) + ". Follower: " + child.getScreenName()); 
        } 
       } 
      } 
     } 
    } catch (TwitterException e) { 
     e.printStackTrace(); 
    } 
    return userList; 
} 

//There definitely are more methods for handling rate limits but this worked for me well 
private void handleRateLimit(RateLimitStatus rateLimitStatus) { 
    //throws NPE here sometimes so I guess it is because rateLimitStatus can be null and add this conditional expression 
    if (rateLimitStatus != null) { 
     int remaining = rateLimitStatus.getRemaining(); 
     int resetTime = rateLimitStatus.getSecondsUntilReset(); 
     int sleep = 0; 
     if (remaining == 0) { 
      sleep = resetTime + 1; //adding 1 more second 
     } else { 
      sleep = (resetTime/remaining) + 1; //adding 1 more second 
     } 

     try { 
      Thread.sleep(sleep * 1000 > 0 ? sleep * 1000 : 0); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

私たちは、このユーザーに直面した深さでプログラム繰り返し同じユーザーをチェックし、保存するのを防ぐために使用されます。

Animated example of a breadth-first search

はここにあなたの問題のための私の実装です。

および個人ユーザーのために、twitter4jライブラリ内isProtected()方法があります。

この実装が役立つことを願っています。

+0

と私は突然、ユーザーのアカウントが保護されているが、我々のアプリケーションに許可を与えた私達のユーザーがその保護されたユーザーは、我々はまた、そのアカウントのフォロワーにアクセスすることができ、次のされている場合、追加するために1つのより多くの事を覚えています。私は自分自身を明確に表現しているかどうかわからないが、そういうものは追加できる... – kadir

関連する問題