使用R语言rvest爬取li标签中人物地点及对应坐标信息求助
实现思路与代码示例
核心步骤
- 提取列表节点的自定义属性:选中页面所有class为
treffer-liste-elem的li节点,提取data-name(姓名,可匹配你已生成的结果表)、data-orte(地点集合)两个属性值生成中间表 - 解析
data-orte结构化数据:该字段规则清晰,不同地点用;分隔,单个地点内部用@分隔为「地点名」「经纬度(逗号分隔纬度、经度)」「地点类型」三个部分,拆分后按类型筛选即可得到出生地(geburt)、死亡地(tod)、活动地(wirk)三类信息 - 关联已有结果:通过姓名匹配将地点信息合并到你已生成的人物基础信息表中,若同一类型有多个地点,可根据需求选择拼接为单个字段,或生成长表每条地点单独一行
完整代码示例
library(rvest) library(dplyr) library(tidyr) # 原有基础爬取逻辑 page = read_html(x = "https://www.deutsche-biographie.de/search?_csrf=45b6ee54-385e-4777-90bf-9067923e6a00&name=meier") name = page %>% html_nodes(".media-heading a") %>% html_text() information = page %>% html_nodes("#secondColumn p") %>% html_text() result = data.frame(name, information, stringsAsFactors = FALSE) # 原有字段处理逻辑 result$yearofbirth = sub("(^[^-]+)-.*", "\\1", result$information) result$yearofdeath = sub(',.*$','', result$information) result$yearofdeath = sub('.*-','', result$yearofdeath) result$profession = sub("^.*?,", "", result$information) result$profession = trimws(result$profession, whitespace = "[ \t\r\n]") result$information = NULL # 新增:提取并解析地点信息 # 1. 提取li节点的自定义属性 location_raw <- page %>% html_nodes(".treffer-liste-elem") %>% tibble( name = html_attr(., "data-name"), orte_raw = html_attr(., "data-orte") ) %>% select(name, orte_raw) # 2. 解析地点字符串 location_parsed <- location_raw %>% # 拆分多个地点 separate_rows(orte_raw, sep = ";") %>% # 拆分单个地点的三个字段 separate(orte_raw, into = c("location", "coord", "type"), sep = "@") %>% # 拆分经纬度为两列 separate(coord, into = c("lat", "lon"), sep = ",", convert = TRUE) # 3. 按类型拆分得到三类地点,合并到基础结果表(以宽表为例,多个活动地用逗号拼接) # 出生地处理 geburt <- location_parsed %>% filter(type == "geburt") %>% group_by(name) %>% summarise( geburt_ort = paste0(location, collapse = ","), geburt_lat = paste0(lat, collapse = ","), geburt_lon = paste0(lon, collapse = ",") ) # 死亡地处理 tod <- location_parsed %>% filter(type == "tod") %>% group_by(name) %>% summarise( tod_ort = paste0(location, collapse = ","), tod_lat = paste0(lat, collapse = ","), tod_lon = paste0(lon, collapse = ",") ) # 活动地处理 wirk <- location_parsed %>% filter(type == "wirk") %>% group_by(name) %>% summarise( wirk_ort = paste0(location, collapse = ","), wirk_lat = paste0(lat, collapse = ","), wirk_lon = paste0(lon, collapse = ",") ) # 4. 关联所有信息到最终结果表 final_result <- result %>% left_join(geburt, by = "name") %>% left_join(tod, by = "name") %>% left_join(wirk, by = "name")
注意事项
- 如果部分人物没有某类地点(比如在世人物没有死亡地),关联后对应字段会自动填充NA,无需额外处理
- 若需要保留每条活动地为单独行,可跳过分类聚合步骤,直接将
location_parsed和基础结果表关联即可 - 页面请求的csrf参数有有效期,实际批量爬取时需要先请求搜索页获取实时csrf参数再发起查询,避免请求失败
内容的提问来源于stack exchange,提问作者natalieee
相关产品推荐
相关产品推荐

