Java: Как легко проверить, был ли URL сокращен?
Если у меня есть общий URL (не ограниченный твиттером или гуглом), например:
http://t.co/y4o14bI
Есть ли простой способ проверить, сокращен ли этот URL?
В вышеприведенном случае я, как человек, могу, конечно, видеть, что оно было сокращенным, но существует ли автоматический и элегантный способ?
11 ответов
Вы можете сделать запрос к URL, посмотреть, если вы будете перенаправлены и, если да, предположим, что это сокращающий сервис. Для этого вам нужно прочитать коды состояния HTTP.
С другой стороны, вы можете внести в белый список некоторые службы сокращения URL (t.co, bit.ly и т. Д.) И предположить, что все ссылки на эти домены сокращены.
Недостатком первого метода является то, что он не уверен, некоторые сайты используют перенаправления внутри. Недостаток второго метода заключается в том, что вам придется продолжать добавлять сокращающие сервисы, хотя только некоторые из них широко используются.
Одним из сигналов может быть запрос URL-адреса и проверка возможности перенаправления на другой домен. Однако без хорошего определения того, что означает "сокращенный", не существует общего способа.
Вот что вы могли бы сделать на Java, Groovy и тому подобное.
- Получите URL, который вы хотите проверить;
- Откройте URL с помощью HttpURLConnection
- Проверьте код ответа
- если это допустимый код, например 200, вы можете извлечь строку URL в длинной форме из объекта подключения, если она была сокращена, или вернуть ее в исходную форму, если это не так.
Мы все любим видеть код, не так ли? Его сырой, но эй!
String addr = "http://t.co/y4o14bI";
URL url = new URL(addr);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if (connection.getResponseCode() == 200) {
String longUrl = connection.url;
System.out.println(longUrl);
} else {
// You decide what you want to do here!
}
Если вы знаете все домены, которые могут быть использованы для сокращения ваших URL, проверьте, содержится ли он:
String[] domains = {"bit.ly", "t.co"...};
for(String domain : domains){
if(url.startsWith("http://" + domain)){
return true;
}
}
return false;
Ты не можешь
Вы можете только проверить, если вы перечислите пару сокращений и проверить, начинается ли URL с него.
Вы также можете попробовать проверить, является ли URL-адрес короче заданной длины (и содержит ли он путь / строку запроса), но некоторые укорачивающие устройства (например, tinyurl) могут иметь более длинные URL-адреса, чем обычные сайты (aol.com)
Я бы предпочел список известных шортнеров.
Вы не можете: вам придется работать по предположению.
Предположение:
- Есть ли
www
существуют в URL. - Имя сервера заканчивается допустимым доменом (например,
com
,edu
и т. д.) или он имеетco.xx
гдеxx
является действительным кодом страны или организации.
И вы можете добавить больше предположений, основанных на других ссылках сокращения URL.
Используйте службу несокращенных URL-адресов, например https://unshorten.me
У них также есть API https://unshorten.me/api
Если URL-адрес сокращен, он вернет исходный URL-адрес. В противном случае вы получите такой же обратно.
Если вы запрашиваете такой URL-адрес, ваш HttpCLient должен получить перенаправление HTTP вместо HTML-страницы. Это будет не доказательство, а хотя бы намек.
Оцените URL и найдите некоторые подсказки:
Путь соответствует определенным критериям
- только один шаг (т.е. не несколько слешей)
- не заканчивается расширениями файлов
- не длиннее X символов (потребуется оценить различные службы сокращения URL-адресов и скорректировать верхние границы для максимальной длины токена)
HttpUrlConnection возвращает код ответа перенаправления (т. Е. 301, 302)
На самом деле, вы, как человек, не можете. Единственный способ узнать, что он сокращен, - это домен t.co. y4o14bI
может быть идентификатором CMS для всего, что вы знаете.
Лучший способ - использовать список известных URL-адресов сокращений и искать их.
И даже тогда у вас будут проблемы. Я использую bit.ly с личным доменом, wtn.gd
Так что http://wtn.gd/random также будет сокращенным URL.
Может быть, вы могли бы сделать HTTP HEAD-запрос и проверить на 301/302?
Я бы предложил использовать android.util.Patterns.WEB_URL
public static List<String> findUrls(String input) {
List<String> links = new ArrayList<>();
Matcher m = android.util.Patterns.WEB_URL.matcher(input);
while (m.find()) {
String url = m.group();
links.add(url);
}
return links;
}