Подтвердить что ты не робот

Есть ли у R какой-либо пакет для разбора частей URL-адреса?

У меня есть список URL-адресов, которые я хотел бы проанализировать и нормализовать.

Я хотел бы иметь возможность разбивать каждый адрес на части, чтобы я мог идентифицировать "www.google.com/test/index.asp" и "google.com/somethingelse" как находящиеся на одном и том же сайте.

4b9b3361

Ответ 1

Так как parse_url() в любом случае использует регулярные выражения, мы также можем изобрести колесо и создать единую замену регулярных выражений, чтобы построить сладкий и причудливый вызов gsub.

Посмотрим. URL-адрес состоит из протокола, "netloc", который может включать имя пользователя, пароль, имя хоста и компоненты порта, а также остаток, который мы счастливо убираем. Предположим сначала, что нет ни имени пользователя, ни пароля, ни порта.

  • ^(?:(?:[[:alpha:]+.-]+)://)? будет соответствовать заголовку протокола (скопирован из parse_url()), мы отменим его, если найдем его
  • Кроме того, потенциальный префикс www. удаляется, но не записывается: (?:www\\.)?
  • Все, что связано с последующей косой чертой, будет нашим полным именем хоста, которое мы фиксируем: ([^/]+)
  • Остальное мы игнорируем: .*$

Теперь мы подключаем регулярные выражения выше, и извлечение имени хоста становится:

PROTOCOL_REGEX <- "^(?:(?:[[:alpha:]+.-]+)://)?"
PREFIX_REGEX <- "(?:www\\.)?"
HOSTNAME_REGEX <- "([^/]+)"
REST_REGEX <- ".*$"
URL_REGEX <- paste0(PROTOCOL_REGEX, PREFIX_REGEX, HOSTNAME_REGEX, REST_REGEX)
domain.name <- function(urls) gsub(URL_REGEX, "\\1", urls)

Изменить имя регулярного выражения хоста для включения (но не захвата) порта:

HOSTNAME_REGEX <- "([^:/]+)(?::[0-9]+)?"

И так далее и так далее, пока мы наконец не придем к регулярному выражению RFC для анализа URL-адресов. Однако для домашнего использования выше должно быть достаточно:

> domain.name(c("test.server.com/test", "www.google.com/test/index.asp",
                "http://test.com/?ex"))
[1] "test.server.com" "google.com"      "test.com"       

Ответ 2

Вы можете использовать функцию пакета R httr

 parse_url(url) 
 >parse_url("http://google.com/")

Вы можете получить более подробную информацию здесь: http://cran.r-project.org/web/packages/httr/httr.pdf

Ответ 3

Также существует пакет urltools, который теперь бесконечно быстрее:

urltools::url_parse(c("www.google.com/test/index.asp", 
                      "google.com/somethingelse"))

##                  scheme         domain port           path parameter fragment
## 1        www.google.com      test/index.asp                   
## 2            google.com       somethingelse                   

Ответ 4

Я бы отказался от пакета и использовал для этого регулярное выражение.

EDIT, переформулированный после атаки робота от Dason...

x <- c("talkstats.com", "www.google.com/test/index.asp", 
    "google.com/somethingelse", "www.stackoverflow.com",
    "http://www.bing.com/search?q=google.com&go=&qs=n&form=QBLH&pq=google.com&sc=8-1??0&sp=-1&sk=")

parser <- function(x) gsub("www\\.", "", sapply(strsplit(gsub("http://", "", x), "/"), "[[", 1))
parser(x)

lst <- lapply(unique(parser(x)), function(var) x[parser(x) %in% var])
names(lst) <- unique(parser(x))
lst

## $talkstats.com
## [1] "talkstats.com"
## 
## $google.com
## [1] "www.google.com/test/index.asp" "google.com/somethingelse"     
## 
## $stackoverflow.com
## [1] "www.stackoverflow.com"
## 
## $bing.com
## [1] "http://www.bing.com/search?q=google.com&go=&qs=n&form=QBLH&pq=google.com&sc=8-1??0&sp=-1&sk="

Это может потребоваться расширить в зависимости от структуры данных.

Ответ 5

Основываясь на ответе R_Newbie, здесь функция, которая будет извлекать имя сервера из URL-адреса (вектора), удаляя префикс www., если он существует, и изящно игнорирует отсутствующий префикс протокола.

domain.name <- function(urls) {
    require(httr)
    require(plyr)
    paths <- laply(urls, function(u) with(parse_url(u),
                                          paste0(hostname, "/", path)))
    gsub("^/?(?:www\\.)?([^/]+).*$", "\\1", paths)
}

Функция parse_url используется для извлечения аргумента path, который далее обрабатывается gsub. Части /? и (?:www\\.)? регулярного выражения будут соответствовать необязательной ведущей косой чертой, за которой следует необязательный www., а [^/]+ соответствует всем после этого, но до первой косой черты - это захватывается и эффективно используется в замените текст вызова gsub.

> domain.name(c("test.server.com/test", "www.google.com/test/index.asp",
                "http://test.com/?ex"))
[1] "test.server.com" "google.com"      "test.com"       

Ответ 6

Если вам нравится tldextract, один из вариантов будет использовать версию appengine

require(RJSONIO)
test <- c("test.server.com/test", "www.google.com/test/index.asp", "http://test.com/?ex")
lapply(paste0("http://tldextract.appspot.com/api/extract?url=", test), fromJSON)
[[1]]
   domain subdomain       tld 
 "server"    "test"     "com" 

[[2]]
   domain subdomain       tld 
 "google"     "www"     "com" 

[[3]]
   domain subdomain       tld 
   "test"        ""     "com"