使用purrr:map和Rselenium循环遍历网页进行数据爬取

3

我有一个基本的R脚本,使用Rselenium拼凑而成。这个脚本可以让我登录到网站,一旦验证成功,我的脚本就会进入到感兴趣的第一个页面,并从该页面提取出3个文本。

幸运的是,URL已经被创建成这样一种形式,以便我可以将数字向量传递给URL,以便跳转到下一个感兴趣的页面。因此,我使用了map()函数。

在每个页面上,我想要爬取相同的3个元素,并将它们存储在主数据框中,以供后续分析。

我希望使用map函数族,以便更加熟悉它们,但我真的很难让它们正常工作。是否有人能够友善地告诉我我错在哪里呢?

这是我的代码主要部分(转到网站并登录):

library(RSelenium)
# https://dev59.com/mVMI5IYBdhLWcg3w1vOi#56173984
rd <- rsDriver(browser = "chrome",
               chromever = "88.0.4324.27",
               port = netstat::free_port())

remdr <- rd[["client"]]

# url of the site's login page
url <- "https://www.myWebsite.com/"

# Navigating to the page
remdr$navigate(url)

# Wait 5 secs for the page to load
Sys.sleep(5)

# Find the initial login button to bring up the username and password fields
loginbutton <- remdr$findElement(using = 'css selector','.plain')

# Click the initial login button to bring up the username and password fields
loginbutton$clickElement()

# Find the username box
username <- remdr$findElement(using = 'css selector','#username')

# Find the password box
password <- remdr$findElement(using = 'css selector','#password')

# Find the final login button
login <- remdr$findElement(using = 'css selector','#btnLoginSubmit1')

# Input the username
username$sendKeysToElement(list("myUsername"))

# Input the password
password$sendKeysToElement(list("myPassword"))

# Click login
login$clickElement()

咔嚓一声,我们就进去了!

现在我的代码将我带到了感兴趣的初始页面(索引 = 1)。

上面我提到了我想逐个浏览每一页,我可以通过将一个整数替换到URL中的rcId元素来实现这一点,如下所示:

#remdr$navigate("https://myWebsite.com/rc_redesign/#/layout/jcard/drugCard?accountId=XXXXXX&rcId=1&searchType=R&reimbCode=&searchTerm=&searchTexts=*") # 转到页面

对于从1到9999的每个rcId,我希望抓取以下3个元素并将它们存储在一个数据框中。

hcpcs_info <- remdr$findElement(using = 'class','is-jcard-heading')

hcpcs <- hcpcs_info$getElementText()[[1]]

hcpcs_description <- remdr$findElement(using = 'class','is-jcard-desc')

hcpcs_desc <- hcpcs_description$getElementText()[[1]]

tc_info <- remdr$findElement(using = 'css selector','.col-12.ng-star-inserted')

therapeutic_class <- tc_info$getElementText()[[1]]

我已经尝试创建一个单独的函数并将其传递给 map 函数,但是我还不够高级,无法将它们组合在一起。以下是我的尝试。

my_function <- function(index) {
  remdr$navigate(sprintf("https://rc2.reimbursementcodes.com/rc_redesign/#/layout/jcard/drugCard?accountId=113479&rcId=%d&searchType=R&reimbCode=*&searchTerm=*&searchTexts=*",index)
                 Sys.sleep(5)
                 hcpcs_info[index] <- remdr$findElement(using = 'class','is-jcard-heading')
                 hcpcs[index] <- hcpcs_info$getElementText()[index][[1]])
}

x <- 1:10 %>% 
map(~ my_function(.x))

非常感谢任何帮助


你的代码输出是什么?它返回错误吗?你想存储哪三个元素? - Ronak Shah
嗨Ronak,我希望返回hcpcs、hcpcs_desc和therapeutic_class。 - TheGoat
1个回答

4

尝试以下内容:

library(RSelenium)

purrr::map_df(1:10, ~{
          remdr$navigate(sprintf("https://rc2.reimbursementcodes.com/rc_redesign/#/layout/jcard/drugCard?accountId=113479&rcId=%d&searchType=R&reimbCode=*&searchTerm=*&searchTexts=*",.x))
          Sys.sleep(5)
          hcpcs_info <- remdr$findElement(using = 'class','is-jcard-heading')
          hcpcs <- hcpcs_info$getElementText()[[1]]
          hcpcs_description <- remdr$findElement(using = 'class','is-jcard-desc')
          hcpcs_desc <- hcpcs_description$getElementText()[[1]]
          tc_info <- remdr$findElement(using = 'css selector','.col-12.ng-star-inserted')
          therapeutic_class <- tc_info$getElementText()[[1]]
          tibble(hcpcs, hcpcs_desc, therapeutic_class)
          }) -> result
result

非常感谢,这太棒了。我刚试了一下,它能用,哇呼!再次感谢。 - TheGoat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接