Инструменты / библиотеки для разрешения / расширения тысяч URL-адресов - PullRequest
4 голосов
/ 13 апреля 2011

В проекте, подобном сканеру, у нас есть распространенная и широко используемая задача для разрешения / расширения тысяч URL-адресов. Скажем, у нас (очень упрощенный пример):

http://bit.ly/4Agih5

GET 'http://bit.ly/4Agih5' запрос возвращает один из 3xx, мы следуем за перенаправлением права на:

http://stackoverflow.com

GET 'http://stackoverflow.com' возвращает 200. Таким образом, «stackoverflow.com» - это результат, который нам нужен.

Любые URL (не только общеизвестные сокращения, такие как bit.ly) допускаются в качестве входных данных. Некоторые из них перенаправляют один раз, некоторые вообще не перенаправляют (в данном случае результатом является сам URL), некоторые перенаправляют несколько раз. Наша задача - как можно больше следовать всем перенаправлениям, имитирующим поведение браузера. В общем, если у нас есть какой-то URL, A преобразователь должен вернуть нам URL B, который должен быть таким же, как если бы A открывается в каком-то браузере.

До сих пор мы использовали Java, пул потоков и простой URLConnection для решения этой задачи. Преимущества очевидны:

  • simplicity - просто создайте URLConnection, установите перенаправления и все (почти);
  • хорошая поддержка HTTP - Java предоставляет все необходимое для максимально имитации браузера: автоматическое отслеживание перенаправлений, поддержка файлов cookie.

К сожалению, у такого подхода есть и недостатки:

  • производительность - темы не бесплатны, URLConnection начинает скачивать документ сразу после getInputStream(), даже если он нам не нужен;
  • объем памяти - точно не уверен, но кажется, что URL и URLConnection - довольно тяжелые объекты, и снова буферизация результата GET сразу после вызова getInputStream().

Существуют ли другие решения (или улучшения этого), которые могут значительно увеличить скорость и уменьшить потребление памяти? Предположительно, нам нужно что-то вроде:

  • высокопроизводительный облегченный Java HTTP-клиент на основе java.nio;
  • C HTTP-клиент, который использует poll () или select ();
  • некоторая готовая библиотека, которая разрешает / расширяет URL;

Ответы [ 2 ]

1 голос
/ 13 апреля 2011

Вы можете использовать Python, Gevent и urlopen.Объедините этот экзамен gevent с обработкой перенаправления в этом вопросе SO .

Я бы не рекомендовал Nutch, он очень сложен в настройке и имеет множество зависимостей (Hadoop, HDFS).

1 голос
/ 13 апреля 2011

Я бы использовал скрипт selenium для чтения URL-адресов из очереди и GET их. Затем подождите около 5 секунд для каждого браузера, чтобы увидеть, происходит ли перенаправление, и, если это так, поместите новый URL-адрес перенаправления обратно в очередь для обработки следующего экземпляра. Вы можете запустить столько экземпляров одновременно, сколько захотите.

UPDATE

Если вам важен только заголовок Location (который использует большинство не-JS или мета-перенаправлений), просто отметьте его, вам никогда не нужно получать inputStream:

HttpURLConnection.setFollowRedirects(false);
URL url = new URL("http://bit.ly/abc123");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
String newLocation = conn.getHeaderField("Location");

Если заполнен newLocation, вставьте этот URL обратно в очередь и выполните следующий раунд.

...