2016-10-05 4 views
1

Я использую Windows 7 с R3.3.1. У меня есть кадр данных, который называется idsFinal_Attack, который имеет два столбца.readLines() webscraping не может открыть соединение в r

Attack Type 
1             40674 
2 Netcore.Netis.Devices.Hardcoded.Password.Security.Bypass 
3         DNS.Invalid.Size.Attack 
4      Acunetix.Web.Vulnerability.Scanner 
5         SIPVicious.SIP.Scanner 
6             17799 
New 
1         SIPVicious.SIP.Scanner 
2 Netcore.Netis.Devices.Hardcoded.Password.Security.Bypass 
3         DNS.Invalid.Size.Attack 
4      Acunetix.Web.Vulnerability.Scanner 
5         SIPVicious.SIP.Scanner 
6        MS.SMBv2.Infinite.Loop.DoS 

Первый - это «Тип атаки», состоящий из символов и числовых идентификаторов. Второй столбец - это то, что я хочу заполнить приведенным ниже кодом.

URL = 'http://www.fortinet.com/ids/VID' 
idsFinal_Attack$New = character(length = nrow(idsFinal_Attack)) 

for (i in 1:nrow(idsFinal_Attack)) { 
    if (is.na(as.numeric(idsFinal_Attack$`Attack Type`[i]))) { 
      idsFinal_Attack$New[i] = idsFinal_Attack$`Attack Type`[i] 
    } else { 
      fortinetPage = readLines(paste0(URL, idsFinal_Attack$`Attack Type`[i])) 
      fortinetPage = grep("id=\"ency_title\">Vulnerability:", fortinetPage, 
           value = TRUE) 
      idsFinal_Attack$New[i] = 
        gsub("<h1 id=\"ency_title\">Vulnerability: |</h1>", "", fortinetPage) 
    } 
} 

Для строк в «Тип атаки», которые содержат строку символов, я хочу, чтобы скопировать и вставить эту строку в соседнюю ячейку столбца «New». Для строк в «Тип атаки», которые содержат числовые записи, такие как строка 1, я хочу вставить это числовое значение в конец переменной «URL», а затем использовать функцию readLines() для извлечения части веб-страницы, которая дополняет «URL», переменная принимает меня, т.е. http://www.fortinet.com/ids/VID40674. Мне нужен только небольшой раздел веб-страницы под названием «Уязвимость» с последующим текстом. readLines() возвращает весь текст с веб-страницы, а затем я могу использовать grep и gsub для получения нужного раздела. Кадр данных idsFinal_Attack имеет 145 строк, 67 из которых являются числовыми и потребует команды readLines(). Код ниже работает примерно для половины из них, а затем выдает ошибку, показанную ниже.

Error in readLines(url(paste0(URL, idsFinal_Attack$`Attack Type`[i]), 
: cannot open the connection 

Это моя первая попытка, и я понимаю, что код можно сделать более кратким. Я просто хотел получить рабочую версию. Я кратко экспериментировал с пакетами XML и rvest, но им не повезло. Есть ли у кого-нибудь предложения?

+0

Не разобрать HTML с регулярным выражением. Используйте парсер HTML, например 'rvest' или' XML'. – alistaire

ответ

1

Я считаю, что readLines может неправильно обрабатывать переадресацию. Поскольку переадресация Fortinet, у вас могут возникнуть проблемы.

Я считаю, что использование rvest более прозрачно, чем использование readLines.

Например, воспроизводимый пример:

library(readr) 
library(rvest) 

sample.data <- "Attack Type New 
40674 SIPVicious.SIP.Scanner 
Netcore.Netis.Devices.Hardcoded.Password.Security.Bypass Netcore.Netis.Devices.Hardcoded.Password.Security.Bypass 
DNS.Invalid.Size.Attack DNS.Invalid.Size.Attack 
Acunetix.Web.Vulnerability.Scanner Acunetix.Web.Vulnerability.Scanner 
SIPVicious.SIP.Scanner SIPVicious.SIP.Scanner 
17799 MS.SMBv2.Infinite.Loop.DoS 
127 MS.SMBv2.Infinite.Loop.DoS" 

idsFinal_Attack <- read_tsv(sample.data) 

URL = 'http://www.fortinet.com/ids/VID' 
idsFinal_Attack$New = character(length = nrow(idsFinal_Attack)) 

for (i in 1:nrow(idsFinal_Attack)) { 
    attack.type <- idsFinal_Attack$`Attack Type`[i] 
    not.fortinet.id <- is.na(as.numeric(attack.type)) 
    if (not.fortinet.id) { 
    idsFinal_Attack$New[i] = attack.type 
    } else { 
    fortinet.url <- paste0(URL, attack.type) 
    fortinet.page <- try(read_html(fortinet.url)) 
    if ("try-error" %in% class(fortinet.page)){ 
     idsFinal_Attack$New[i] <- NA 
     next; 
    } 
    title <- fortinet.page %>% 
     html_node(xpath = ".//*[@id='ency_title']") %>% 
     html_text() 
    title.clean <- gsub("^\\w+:\\s+", "", title) 
    idsFinal_Attack$New[i] <- title.clean 
    } 
} 
+0

- это функция «read_tsv», которая должна воссоздать фрейм данных «idsFinal_Attack», который я изначально разместил? –

+0

Да, это так. –

+0

, используя исходный фрейм данных idsFinal_Attack, ваше решение отлично работало для всех URL-адресов, отображаемых на веб-странице. Однако был один (http://www.fortinet.com/ids/VID127), в котором была сделана следующая ошибка: «Ошибка в open.connection (x,« rb »): ошибка HTTP 404.». Причина, по-моему, состоит в том, что «Страница не найдена». Это произошло в середине выполнения кода и заставило код прекратить выполнение с 80 оставшимися строками. Есть ли способ обойти это, чтобы код продолжал работать, и сообщение, подобное «неразрешенному», помещается в ячейку, где должны были пройти веб-данные? –

Смежные вопросы