Разбор ссылок с JTidy - PullRequest
       42

Разбор ссылок с JTidy

1 голос
/ 20 декабря 2011

В настоящее время я использую JTidy для анализа HTML-документа и извлечения коллекции всех тегов привязки в данном HTML-документе.Затем я извлекаю значение атрибута href каждого тега, чтобы создать коллекцию ссылок на странице.

К сожалению, эти ссылки можно выразить несколькими различными способами: некоторые абсолютные (http://www.example.com/page.html), некоторыеотносительный (/page.html, page.html или ../page.html).Более того, некоторые из них могут быть просто якорями (#paragraphA).Когда я захожу на мою страницу в браузере, он автоматически знает, как обрабатывать эти различные значения href, если я нажму на ссылку, однако, если я буду следовать одной из этих ссылок, полученных из JTidy с использованием HTTPClient программно, мне сначала нужно предоставитьдействительный URL (так, например, мне сначала нужно преобразовать /page.html, page.html и http://www.example.com/page.html в http://www.example.com/page.html).

Есть ли какие-то встроенные функции, будь то в JTidy илив другом месте, что может достичь этого для меня? Или мне нужно будет создать свои собственные правила для преобразования этих различных URL-адресов в абсолютный URL-адрес?

Ответы [ 2 ]

3 голосов
/ 20 декабря 2011

Класс vanilla URL может помочь вам в этом, если вы сможете решить, какой контекст использовать. Вот несколько примеров:

package grimbo.url;

import java.net.MalformedURLException;
import java.net.URL;

public class TestURL {
    public static void main(String[] args) {
        // context1
        URL c1 = u(null, "http://www.example.com/page.html");
        u(c1, "http://www.example.com/page.html");
        u(c1, "/page.html");
        u(c1, "page.html");
        u(c1, "../page.html");
        u(c1, "#paragraphA");

        System.out.println();

        // context2
        URL c2 = u(null, "http://www.example.com/path/to/page.html");
        u(c2, "http://www.example.com/page.html");
        u(c2, "/page.html");
        u(c2, "page.html");
        u(c2, "../page.html");
        u(c2, "#paragraphA");
    }

    public static URL u(URL context, String url) {
        try {
            URL u = null != context ? new URL(context, url) : new URL(url);
            System.out.println(u);
            return u;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Результат:

http://www.example.com/page.html
http://www.example.com/page.html
http://www.example.com/page.html
http://www.example.com/page.html
http://www.example.com/../page.html
http://www.example.com/page.html#paragraphA

http://www.example.com/path/to/page.html
http://www.example.com/page.html
http://www.example.com/page.html
http://www.example.com/path/to/page.html
http://www.example.com/path/page.html
http://www.example.com/path/to/page.html#paragraphA

Как видите, есть некоторые результаты, которые не соответствуют вашим ожиданиям. Поэтому, возможно, вы сначала попытаетесь проанализировать URL-адрес, используя new URL(value), и, если это приведет к MalformedURLException, вы можете попробовать сделать это относительно контекстного URL-адреса.

1 голос
/ 20 декабря 2011

Лучше всего вы, скорее всего, будете следовать тому же процессу разрешения, что и браузеры, как указано в спецификации HTML :

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

  1. Базовый URI устанавливается элементом BASE.
  2. Базовый URI задается метаданными, обнаруженными во время взаимодействия протокола, напримерв качестве заголовка HTTP (см. [RFC2616]).
  3. По умолчанию базовый URI соответствует текущему документу.Не все HTML-документы имеют базовый URI (например, действительный HTML-документ может появиться в электронном письме и не может быть обозначен URI).Такие HTML-документы считаются ошибочными, если они содержат относительные URI и полагаются на базовый URI по умолчанию.

На практике вы, вероятно, больше всего обеспокоены числами 1 и 2 (т. Е. Проверьте наличие<base href="..." и используйте либо это (если оно существует), либо URI текущего документа).

...