在R中处理爬取数据:拆分列表及无法获取瑞士医生完整地址的问题
R语言网页爬取问题解答
问题1:如何在R中拆分(Unlist)爬取到的信息?
爬取网页时,用lapply()/map()提取元素文本后通常会得到列表结构,拆分的核心是把多层/嵌套列表转成扁平的向量或数据框列,常用方法:
- 基础R的
unlist():直接将单层列表转为向量,适合简单场景:# 示例:将爬取的标题列表转为向量 title_list <- list("Dr. Anna", "Dr. Bob", "Dr. Charlie") title_vec <- unlist(title_list) - tidyverse的
flatten_chr():专门处理字符型列表,比unlist()更严谨,避免类型混乱,比如你代码中用到的:Titles <- lapply(doc_titles, function(x) x$getElementText() %>% unlist()) %>% flatten_chr() - 多层嵌套列表:如果爬取的信息是嵌套结构(比如每个元素下还有子列表),可以用
unlist(recursive = TRUE)或flatten()系列函数(flatten_dbl()/flatten_lgl()对应不同数据类型)。
问题2:爬取医生点击后的完整地址信息
你当前代码仅获取了列表页的基础信息,完整地址需要点击医生卡片触发弹窗后提取,以下是修改后的核心逻辑:
核心步骤:
- 定位所有可点击的医生卡片元素,而非仅标题
- 循环遍历每个卡片,点击后等待弹窗加载
- 提取弹窗内的完整地址,再关闭弹窗继续处理下一个
修改后的代码片段(整合到原有代码的滚动加载步骤之后):
# 替换原有的标题/位置提取逻辑,改为获取所有医生卡片 doc_cards <- remDr$findElements(using = 'xpath', '//div[contains(@class, "search-result-item")]') # 初始化存储结果的列表 doctor_data <- list() # 循环处理每个医生卡片 for (i in seq_along(doc_cards)) { # 滚动到当前卡片位置,避免元素被遮挡 remDr$executeScript("arguments[0].scrollIntoView(true);", list(doc_cards[[i]])) Sys.sleep(1) # 点击卡片触发弹窗 doc_cards[[i]]$clickElement() Sys.sleep(2) # 等待弹窗加载完成 # 提取弹窗内的完整地址(需根据实际网页结构调整xpath) full_address <- tryCatch({ addr_elem <- remDr$findElement(using = 'xpath', '//div[contains(@class, "address-details")]') addr_elem$getElementText() %>% unlist() }, error = function(e) NA_character_) # 提取医生姓名和基础位置(也可从弹窗内提取,更准确) doc_name <- tryCatch({ name_elem <- remDr$findElement(using = 'xpath', '//h2[contains(@class, "profile-name")]') name_elem$getElementText() %>% unlist() }, error = function(e) NA_character_) doc_basic_loc <- tryCatch({ loc_elem <- remDr$findElement(using = 'xpath', '//div[contains(@class, "profile-location")]') loc_elem$getElementText() %>% unlist() }, error = function(e) NA_character_) # 存储当前医生数据 doctor_data[[i]] <- data.frame( Name = doc_name, Basic_Location = doc_basic_loc, Full_Address = full_address, stringsAsFactors = FALSE ) # 关闭弹窗(根据实际网页调整关闭按钮的xpath) close_btn <- remDr$findElement(using = 'xpath', '//button[contains(@class, "modal-close-btn")]') close_btn$clickElement() Sys.sleep(1) } # 合并所有数据为最终数据框 final_df <- dplyr::bind_rows(doctor_data)
注意事项:
- 网页元素的xpath可能随网站更新变化,需用浏览器开发者工具(F12)重新定位弹窗地址、关闭按钮等元素
- 加入
tryCatch()避免单个元素提取失败导致整个循环中断 - 根据网页加载速度调整
Sys.sleep()的时长,避免因加载不完整导致提取失败 - 如果点击卡片后打开新页面而非弹窗,需用
remDr$getWindowHandles()切换窗口,提取信息后再切回原窗口
内容的提问来源于stack exchange,提问作者Avdyl Bytyqi
相关产品推荐
相关产品推荐

