【问题标题】:Issue using Twitter REST API使用 Twitter REST API 的问题
【发布时间】:2010-06-24 19:49:44
【问题描述】:

我在 Twitter 上有一个用户名列表,我希望获取有关他们 Twitter 个人资料的元数据。我也在使用 Twitter 的REST API users/show 方法适合我的任务。 API 文档明确指出它不需要身份验证。这是我为我的任务编写的代码:

package Twitter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class TwitterAPI {

    private static String url = "http://api.twitter.com/1/users/show/";

    /*
     * Sends a HTTP GET request to a URL     
     * @return - The response from the end point
     */
    public static String sendGetRequest(String endpoint, String screen_name) {
        String result = null;


        if (endpoint.startsWith("http://")){
            //Send HTTP request to the servlet
            try {
                //Construct data
                StringBuffer data = new StringBuffer();

                //Send data
                String urlStr = endpoint ;  

                if(screen_name!=null && screen_name.length() > 0){
                    urlStr += screen_name + ".json";
                }
                System.out.println(screen_name.length());
                System.out.println("The URL call is: " + urlStr);
                URL url = new URL(urlStr);
                URLConnection conn = url.openConnection ();

                //Get the response
                BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                StringBuffer sb = new StringBuffer();
                String line;

                while((line = rd.readLine())!=null){
                    sb.append(line);
                }

                rd.close();
                result = sb.toString();

            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {

                //If API issue, collect screen names to write to API issue file             
                System.out.println("Twitter API issue :" + screen_name);

                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


        return result;
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        String result = sendGetRequest(url, "denzil_correa");
        System.out.println(result);
    }

}

但是,在运行相同的程序时,我收到以下异常:

13
The URL call is: http://api.twitter.com/1/users/show/denzil_correa.json
Twitter API issue :denzil_correa
java.net.ConnectException: Connection timed out: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:365)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:227)
null
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:214)
    at java.net.Socket.connect(Socket.java:531)
    at java.net.Socket.connect(Socket.java:481)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:394)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:529)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:233)
    at sun.net.www.http.HttpClient.New(HttpClient.java:306)
    at sun.net.www.http.HttpClient.New(HttpClient.java:323)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:783)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:724)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:649)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:972)
    at Twitter.TwitterAPI.sendGetRequest(TwitterAPI.java:43)
    at Twitter.TwitterAPI.main(TwitterAPI.java:76)

当我在浏览器中尝试 URL 时,URL 是正确的:http://api.twitter.com/1/users/show/denzil_correa.json 我收到以下信息:

{"time_zone":"Mumbai","description":"","lang":"en","profile_link_color":"1F98C7","status":{"coordinates":null,"contributors":null,"in_reply_to_screen_name":"shailaja","truncated":false,"in_reply_to_user_id":14089830,"in_reply_to_status_id":16789217674,"source":"web","created_at":"Tue Jun 22 19:43:46 +0000 2010","place":null,"geo":null,"favorited":false,"id":16793898396,"text":"@shailaja Harsh !"},"profile_background_image_url":"http://s.twimg.com/a/1276711174/images/themes/theme2/bg.gif","profile_sidebar_fill_color":"DAECF4","following":false,"profile_background_tile":false,"created_at":"Sun Jun 29 20:23:29 +0000 2008","statuses_count":1157,"profile_sidebar_border_color":"C6E2EE","profile_use_background_image":true,"followers_count":169,"contributors_enabled":false,"notifications":false,"friends_count":246,"protected":false,"url":"http://https://sites.google.com/a/iiitd.ac.in/denzilc/","profile_image_url":"http://a3.twimg.com/profile_images/643636081/Cofee_Mug_normal.jpg","geo_enabled":true,"profile_background_color":"C6E2EE","name":"Denzil Correa","favourites_count":3,"location":"India","screen_name":"denzil_correa","id":15273105,"verified":false,"utc_offset":19800,"profile_text_color":"663B12"}

这是我想要的 JSON 格式。

如果我在这里做任何愚蠢的事情,请告诉我。

问候, --登齐尔


Hank/Splix 告诉我我尝试使用 HTTP Components Client。这是我修改后的代码:

 
package Twitter;

import java.io.IOException;

import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.client.DefaultHttpClient;

public class TwitterAPI {

private static String url = "http://api.twitter.com/1/users/show/denzil_correa.json";


/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

    HttpClient httpclient = new DefaultHttpClient();
    HttpGet httpget = new HttpGet(url);

    try {
        HttpResponse response = httpclient.execute(httpget);
        System.out.println(response.toString());

    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

这是我收到的错误:
 
org.apache.http.conn.HttpHostConnectException: Connection to @987654325@ refused
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:127)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
    at Twitter.TwitterAPI.main(TwitterAPI.java:30)
Caused by: java.net.ConnectException: Connection timed out: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:365)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:227)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:214)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:378)
    at java.net.Socket.connect(Socket.java:531)
    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:123)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:123)
    ... 7 more
令人惊讶的是,这也给为手动处理 HTTP 响应而编写的代码提供了类似的异常。我知道手动处理 HTTP 响应可能不是最佳的,但目前我并没有考虑编写最佳代码。我想完成我的任务,即使这意味着快速和肮脏。

只是让您知道,我可以使用我发布的第一个代码成功调用Facebook Graph API 。如果我将 URL 粘贴到浏览器中,我会收到相同的响应。

我还将再次尝试使用 Twitter4J API 并检查是否可以完成我的任务。会及时通知您。


所以,这里是使用 Twitter4J 的代码:


package Twitter;

import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.User;

public class TwitterAPI {

/**
 * @param args
 */
public static void main(String[] args) {
    Twitter unauthenticatedTwitter = new TwitterFactory().getInstance();
    try {
        User user = unauthenticatedTwitter.showUser("denzil_correa");

        System.out.println(user.getLocation());
    } catch (TwitterException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

使用 API 就像预期的那样非常简单。但是,这是我收到的错误:

Jun 23, 2010 7:12:10 PM twitter4j.internal.logging.CommonsLoggingLogger info
INFO: Using class twitter4j.internal.logging.CommonsLoggingLoggerFactory as logging factory.
Jun 23, 2010 7:12:11 PM twitter4j.internal.logging.CommonsLoggingLogger info
INFO: Use twitter4j.internal.http.HttpClientImpl as HttpClient implementation.
TwitterException{statusCode=-1, retryAfter=0, rateLimitStatus=null}
    at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:316)
    at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:68)
    at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:90)
    at twitter4j.Twitter.showUser(Twitter.java:538)
    at Twitter.TwitterAPI.main(TwitterAPI.java:17)
Caused by: java.net.ConnectException: Connection refused: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:365)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:227)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:214)
    at java.net.Socket.connect(Socket.java:531)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:152)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:394)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:529)
    at com.ibm.net.ssl.www2.protocol.https.c.(c.java:166)
    at com.ibm.net.ssl.www2.protocol.https.c.a(c.java:9)
    at com.ibm.net.ssl.www2.protocol.https.d.getNewHttpClient(d.java:55)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:724)
    at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:20)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:972)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:385)
    at com.ibm.net.ssl.www2.protocol.https.b.getResponseCode(b.java:52)
    at twitter4j.internal.http.HttpResponseImpl.(HttpResponseImpl.java:42)
    at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:279)
    ... 4 more

再次,我看到错误基本上是相同的。所以,所有的选择都试过了!我确定我在这里缺少一些东西。如果你能指出同样的事情,那就太好了。


汉克,不幸的是,这同样不适用于 Python :-(


Traceback (most recent call last):
  File "", line 1, in 
    urllib.urlopen("@987654327@").read()
  File "C:\Python26\lib\urllib.py", line 86, in urlopen
    return opener.open(url)
  File "C:\Python26\lib\urllib.py", line 205, in open
    return getattr(self, name)(url)
  File "C:\Python26\lib\urllib.py", line 347, in open_http
    errcode, errmsg, headers = h.getreply()
  File "C:\Python26\lib\httplib.py", line 1060, in getreply
    response = self._conn.getresponse()
  File "C:\Python26\lib\httplib.py", line 986, in getresponse
    response.begin()
  File "C:\Python26\lib\httplib.py", line 391, in begin
    version, status, reason = self._read_status()
  File "C:\Python26\lib\httplib.py", line 349, in _read_status
    line = self.fp.readline()
  File "C:\Python26\lib\socket.py", line 397, in readline
    data = recv(1)
IOError: [Errno socket error] [Errno 10054] An existing connection was forcibly closed by the remote host

【问题讨论】:

  • 为什么不使用twitter4j,或者至少使用commons httpclient
  • @splix 你应该把它变成一个答案,这样我就可以投票了。
  • 感谢斯普利克斯!我从来不知道存在一个 http-components-client。以后我将使用相同的方法来处理 HTTP 请求/响应。我尝试使用相同的方法,但它并没有解决我的问题。更多描述在我的原始帖子的编辑中。
  • Hanx/Splix,请查看我的最新编辑。我也试过 Twitter4J。没有帮助解决问题。如果您能指出问题,那就太好了。谢谢:-)
  • 也许您在浏览器中使用了代理,不是吗?您是否尝试打开与其他网站的连接以验证连接?

标签: java twitter


【解决方案1】:

正如 @splix 在 cmets 中提到的那样,仅使用 java.net 执行此操作是……次优的。我从未遇到过HttpClient 不是更好选择的情况。事件更好的是他的twitter4j的建议;除非您尝试创建替代方案,否则使用这样的 API 包装器几乎总是比自己处理原始 HTTP 交互更好。

更新:

@Denzil 很奇怪,即使使用twitter4j,你也会遇到同样的错误(我无法测试代码,直到我有空闲时间来获取库等)所以我开始怀疑有问题推特结束。如果您安装了 Python,请尝试以下操作:

>>> import urllib
>>> urllib.urlopen("http://api.twitter.com/1/users/show/denzil_correa.json").read()

这对我有用。

更新 2:

这听起来绝对像是 Twitter 故意拒绝你的请求。可能的原因可能包括:您的 IP 出于某种原因在他们的黑名单上、代理巫毒或我没有想到的事情。详细说明代理伏都教:我不知道它对您的请求究竟做了什么,但它可能会添加一个标头或 Twitter API 不喜欢的东西。我建议联系 Twitter 支持(如果有这样的 API 问题)或发帖到 the mailing list

顺便说一句,这里有一个thread from the mailing list,其中提到了查看您是否被列入黑名单的方法。

【讨论】:

  • Hank/Splix,感谢您的回复。我对 Twitter4J 的体验很糟糕。 API 为我返回了不稳定的结果,即。它有时会返回结果,有时则不会。
  • 汉克,在 Python 中尝试过同样的方法。不行! :-O 检查我的编辑是否有错误。
  • 汉克,再次感谢您的更新。但是,如果我可以通过在浏览器中发布来获取详细信息,为什么我通过代码进行操作时会出现问题?
  • 正如@splix 提到的,来自浏览器的代理请求和来自代码的代理请求之间可能存在差异。您可以尝试检查来自浏览器的请求的标头,并将它们与来自代码的请求进行比较。
  • 汉克,感谢您的回复。仍然让我感到困惑的是,我使用代码本身来访问 Facebook API,而没有在我的代码中使用任何代理身份验证。因此,如果 Facebook API 不需要它,我相信在使用 Twitter 时也不需要它。最终,这两个请求都是简单的 HTTP 请求,需要以相同的方式处理。这种不一致仍然让我头疼。
猜你喜欢
  • 2016-02-08
  • 2013-06-16
  • 2013-07-27
  • 2013-06-18
  • 2014-07-29
  • 2015-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多