Извлеките имя JPG из URL, используя R - PullRequest
0 голосов
/ 01 ноября 2018

кто-то может мне помочь, это моя проблема: У меня есть список URL в таблице, и я должен извлечь JPG Nane. это URL https://content_xxx.xxx.com/vp/969ffffff61/5C55ABEB/t51.2ff5-15/e35/13643048_612108275661958_805860992_n.jpg?ff_cache_key=fffffQ%3ff%3D.2 и эта часть, чтобы извлечь 13643048_612108275661958_805860992_n спасибо за помощь

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Поиск в Google для "R parse URL" мог бы избавить вас от набора ~ 400 нажатий клавиш (хотя я ожидаю, что URL был вставлен).

В любом случае, вы хотите обработать вектор этих вещей, так что есть лучший способ. На самом деле есть несколько способов сделать это извлечение пути URL в R. Вот 3:

library(stringi)
library(urltools)
library(httr)
library(XML)
library(dplyr)

Мы создадим 100 уникальных URL-адресов, которые соответствуют одному и тому же шаблону Instagram (ПРИМЕЧАНИЕ: удаление instagram является нарушением их ToS и контролируется robots.txt. Если ваши URL-адреса не были получены из API Instagram, пожалуйста, сообщите мне об этом Я могу удалить этот ответ, так как не помогаю ворам контента).

set.seed(0)

paste(
  "https://content_xxx.xxx.com/vp/969ffffff61/5C55ABEB/t51.2ff5-15/e35/13643048_612108275661958_805860992_n.jpg?ff_cache_key=fffffQ%3ff%3D.2",
  stri_rand_strings(100, 8, "[0-9]"), "_",
  stri_rand_strings(100, 15, "[0-9]"), "_",
  stri_rand_strings(100, 9, "[0-9]"), "_",
  stri_rand_strings(100, 1, "[a-z]"),
  ".jpg?ff_cache_key=MTMwOTE4NjEyMzc1OTAzOTc2NQ%3D%3D.2",
  sep=""
) -> img_urls

head(img_urls)
## [1] "https://content_xxx.xxx.com/vp/969ffffff61/5C55ABEB/t51.2ff5-15/e35/13643048_612108275661958_805860992_n.jpg?ff_cache_key=fffffQ%3ff%3D.2"
## [2] "https://https://content_xxx.xxx.com/vp/969b7087cc97408ccee167d473388761/5C55ABEB/t51.2885-15/e35/66021637_359927357880233_471353444_q.jpg?ff_cache_key=MTMwOTE4NjEyMzc1OTAzOTc2NQ%3D%3D.2"
## [3] "https://https://content_xxx.xxx.com/vp/969b7087cc97408ccee167d473388761/5C55ABEB/t51.2885-15/e35/47937926_769874508959124_426288550_z.jpg?ff_cache_key=MTMwOTE4NjEyMzc1OTAzOTc2NQ%3D%3D.2"
## [4] "https://https://content_xxx.xxx.com/vp/vp/969b7087cc97408ccee167d473388761/5C55ABEB/t51.2885-15/e35/12303834_440673970920272_460810703_n.jpg?ff_cache_key=MTMwOTE4NjEyMzc1OTAzOTc2NQ%3D%3D.2"
## [5] "https://https://content_xxx.xxx.com/vp/969b7087cc97408ccee167d473388761/5C55ABEB/t51.2885-15/e35/54186717_202600346704982_713363439_y.jpg?ff_cache_key=MTMwOTE4NjEyMzc1OTAzOTc2NQ%3D%3D.2"
## [6] "https://https://content_xxx.xxx.com/vp/969b7087cc97408ccee167d473388761/5C55ABEB/t51.2885-15/e35/48675570_402479399847865_689787883_e.jpg?ff_cache_key=MTMwOTE4NjEyMzc1OTAzOTc2NQ%3D%3D.2"

Теперь давайте попробуем разобрать эти URL:

invisible(urltools::url_parse(img_urls))

invisible(httr::parse_url(img_urls))
## Error in httr::parse_url(img_urls): length(url) == 1 is not TRUE

DOH! httr не может этого сделать.

invisible(XML::parseURI(img_urls))
## Error in if (is.na(uri)) return(structure(as.character(uri), class = "URI")): the condition has length > 1

DOH! XML тоже не может этого сделать.

Это означает, что нам нужно использовать костыль sapply() для httr и XML, чтобы получить компонент пути (вы можете запустить basename() для любого результирующего вектора, как показал Конрад):

data_frame(
  urltools = urltools::url_parse(img_urls)$path,
  httr = sapply(img_urls, function(URL) httr::parse_url(URL)$path, USE.NAMES = FALSE),
  XML = sapply(img_urls, function(URL) XML::parseURI(URL)$path, USE.NAMES = FALSE)
) -> paths

glimpse(paths)
## Observations: 100
## Variables: 3
## $ urltools <chr> "vp/969b7087cc97408ccee167d473388761/5C55ABEB/t51.2885-15/e35/82359289_380972639303339_908467218_h...
## $ httr     <chr> "vp/969b7087cc97408ccee167d473388761/5C55ABEB/t51.2885-15/e35/82359289_380972639303339_908467218_h...
## $ XML      <chr> "/vp/969b7087cc97408ccee167d473388761/5C55ABEB/t51.2885-15/e35/82359289_380972639303339_908467218_...

Обратите внимание на не совсем стандартное включение начальных символов, / в путь от XML. Это не важно для вас в этом примере, но важно отметить разницу в целом.

Мы обработаем один из них, так как XML и httr имеют это печальное ограничение:

microbenchmark::microbenchmark(
  urltools = urltools::url_parse(img_urls[1])$path,
  httr = httr::parse_url(img_urls[1])$path,
  XML = XML::parseURI(img_urls[1])$path
)
## Unit: microseconds
##      expr     min       lq      mean   median       uq      max neval
##  urltools 351.268 397.6040 557.09641 499.2220 618.5945 1309.454   100
##      httr 550.298 619.5080 843.26520 717.0705 888.3915 4213.070   100
##       XML  11.858  16.9115  27.97848  26.1450  33.9065  109.882   100

XML выглядит быстрее, но на практике это не так:

microbenchmark::microbenchmark(
  urltools = urltools::url_parse(img_urls)$path,
  httr = sapply(img_urls, function(URL) httr::parse_url(URL)$path, USE.NAMES = FALSE),
  XML = sapply(img_urls, function(URL) XML::parseURI(URL)$path, USE.NAMES = FALSE)
)
## Unit: microseconds
##      expr       min        lq      mean     median        uq        max neval
##  urltools   718.887   853.374  1093.404   918.3045  1146.540   2872.076   100
##      httr 58513.970 64738.477 80697.548 68908.7635 81549.154 224157.857   100
##       XML  1155.370  1245.415  2012.660  1359.8215  1880.372  26184.943   100

Если вы действительно хотите пойти по пути регулярных выражений, вы можете прочитать RFC для URL BNF и наивное регулярное выражение для взлома битов из одного, а Google - для оригинального примера с более чем дюжиной регулярных выражений, которые обрабатывают не очень. хорошо сформированные URI, но синтаксический анализ, как правило, является лучшей стратегией для разнообразного содержимого URL. В вашем случае разбиение и регулярное выражение может работать просто отлично, но это не обязательно будет намного быстрее, чем анализ:

microbenchmark::microbenchmark(
  urltools = tools::file_path_sans_ext(basename(urltools::url_parse(img_urls)$path)),
  httr = tools::file_path_sans_ext(basename(sapply(img_urls, function(URL) httr::parse_url(URL)$path, USE.NAMES = FALSE))),
  XML = tools::file_path_sans_ext(basename(sapply(img_urls, function(URL) XML::parseURI(URL)$path, USE.NAMES = FALSE))),
  regex = stri_match_first_regex(img_urls, "/([[:digit:]]{8}_[[:digit:]]{15}_[[:digit:]]{9}_[[:alpha:]]{1})\\.jpg\\?")[,2]
)
## Unit: milliseconds
##      expr       min        lq      mean    median        uq        max neval
##  urltools  1.140421  1.228988  1.502525  1.286650  1.444522   6.970044   100
##      httr 56.563403 65.696242 77.492290 69.809393 80.075763 157.657508   100
##       XML  1.513174  1.604012  2.039502  1.702018  1.931468  11.306436   100
##     regex  1.137204  1.223683  1.337675  1.260339  1.397273   2.241121   100

Как отмечалось в последнем примере, вам нужно запустить tools::file_path_sans_ext() для результата, чтобы удалить .jpg (или sub() его).

0 голосов
/ 01 ноября 2018

Это требует двух вещей:

  1. парсинг самого URL
  2. получить имя файла из пути URL

Вы можете сделать оба вручную, но намного лучше использовать существующие инструменты. Первая часть решается с помощью функции parseURI из пакета ‹XML:

uri = 'https://content_xxx.xxx.com/vp/969ffffff61/5C55ABEB/t51.2ff5-15/e35/13643048_612108275661958_805860992_n.jpg?ff_cache_key=fffffQ%3ff%3D.2
parts = XML::parseURI(uri)

И вторая часть тривиально решается функцией basename:

filename = basename(parts$path)
...