readLines()webscraping无法在r

时间:2016-10-05 23:38:20

标签: r web-scraping

我正在使用带有R3.3.1的Windows 7。我有一个名为idsFinal_Attack的数据框,有两列。

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  

第一个是"攻击类型"由字符和数字ID组成。第二列是我希望填写下面的代码。

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)
    }
}

对于&#34;攻击类型&#34;中的行我想包含一个字符串,我希望将该字符串复制并粘贴到列#34; New&#34;的相邻单元格中。对于&#34;攻击类型&#34;中的行包含数字条目,如第1行,我希望将该数值粘贴到变量&#34; URL&#34;的末尾,然后使用readLines()函数提取扩充&的网页的一部分#34; URL&#34;变量带我去,即http://www.fortinet.com/ids/VID40674。我只需要一小部分名为&#34; Vulnerability&#34;随后的文字。 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包,但没有任何幸运。有人有什么建议吗?

1 个答案:

答案 0 :(得分: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  
  }
}