R语言爬取ZDF德国研究网页:无城市名URL下提取80城Verkehrssicherheit排名实现疑问
ZDF老年与家庭研究页面城市指标爬取实操方案
解决URL拼接失效问题:搭建城市名与地区编号的映射关系
- 放弃直接用城市名拼接详情页URL的思路,这类站点的前端查询逻辑全部依赖内置的城市-地区编号映射表:打开目标站点首页,调出浏览器开发者工具的网络面板,手动触发一次城市搜索操作,筛选XHR类型的请求,找到返回匹配城市列表的接口,直接把全量映射JSON抓下来,不需要逐页爬取找编号。
- 拿到映射表后,从表中匹配你需要的80个城市对应的地区编号,把原来的纯城市名向量替换为带编号的映射数据表,循环时直接用编号拼接URL即可,修改后的核心逻辑示例:
# 替换原参考代码的纯城市名向量为带编号的映射结构 city_targets = data.frame( city_name = c("Munich", "Cologne"), district_code = c("05754", "03104") # 从抓取的映射JSON中匹配填值 ) for (i in seq_len(nrow(city_targets))) { current_code = city_targets$district_code[i] # 直接用地区编号拼接详情页地址,无需嵌入城市名 detail_page = paste0( "https://deutschland-studie-senioren-familie.zdf.de/senioren/district/", current_code ) # 后续页面解析逻辑正常执行即可 }
实现自动遍历查询的循环逻辑
- 不需要模拟搜索框手动输入、点击这类前端交互动作:已经拿到全量城市编号后,直接跳过前端查询环节,拼接对应编号的详情页URL发起请求,相比模拟人工操作的方案,稳定性和效率都会大幅提升,也不容易触发反爬拦截。
- 循环过程中做两个基础保障:一是每次请求完成后添加1-2秒的随机间隔,避免请求频率过高被站点封禁;二是给请求添加正常浏览器的User-Agent头,不要使用R默认的请求标识。
- 循环中加入错误捕获机制,单条请求失败时不要直接中断全量任务,把失败的条目单独记录下来后续补爬即可,示例基础结构:
library(httr) library(rvest) fetch_city_data = function(district_code) { page_url = paste0("https://deutschland-studie-senioren-familie.zdf.de/senioren/district/", district_code) tryCatch({ resp = GET( page_url, user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36") ) page_html = read_html(resp) # 后续解析逻辑 return(list(status = "success", data = extracted_values)) }, error = function(err) { return(list(status = "failed", code = district_code, err_msg = err$message)) }) }
解决目标指标定位障碍的实操技巧
- 不要再从全页面范围用SelectorGadget找元素:先通过文本匹配定位到"Sicherheit und Infrastruktur"分类的整块DOM节点,把查找范围缩小到这个分类块内部,能排除80%以上的选择器干扰。
- 分层定位的操作步骤:
- 用XPath表达式定位目标分类模块:
//*[contains(text(), 'Sicherheit und Infrastruktur')]/parent::div,把整个分类的HTML节点提取出来。 - 在这个缩小后的节点范围内,再定位包含"Verkehrssicherheit"文本的指标行,顺着行结构找到相邻的、存放排名值的节点即可——这类调研页的指标行都是固定的“指标名称-评分-排名”三列相邻结构,不需要依赖复杂的CSS类名就能定位。
- 用XPath表达式定位目标分类模块:
- 如果遇到SelectorGadget始终定位不准的情况,可以直接从页面内嵌的script标签里提取JSON格式的全量指标数据,完全绕开DOM元素定位的环节,直接用文本匹配提取对应指标的排名值,效率更高。
内容的提问来源于stack exchange,提问作者meg1234
相关产品推荐
相关产品推荐

