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;
}
Другие вопросы по тегам