【发布时间】: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。没有帮助解决问题。如果您能指出问题,那就太好了。谢谢:-)
-
也许您在浏览器中使用了代理,不是吗?您是否尝试打开与其他网站的连接以验证连接?