R语言爬取澳大利亚黄页水管工列表构建tibble列长度不匹配咨询
报错核心原因
原有提取逻辑直接全局遍历整页HTML抓取符合选择器规则的字段节点:页面上36个商户里,只有17个登记了电话号码,未登记电话的商户会被直接跳过,最终生成的电话向量长度仅为17,和长度为36的商户名称向量不匹配,触发tibble列长不一致的报错。
修正思路
不再跨页面全局收集所有匹配的字段值,而是先按独立商户条目拆分页面块,在每个块内部定向提取对应字段,无匹配内容时自动填充NA,保证所有字段向量的长度和商户总数完全对齐。
具体实现步骤
- 定位页面上所有商户条目的统一容器(目标站点单条商户的容器类为
.listing),将整页HTML拆分为独立的单条节点列表,列表长度即为页面的商户总数。 - 逐节点提取三类字段,提取时使用单数形式的
html_node,保证每个节点最多取一个匹配结果,避免多抓导致的长度偏差。 - 用映射函数统一处理每个节点的提取逻辑,节点不存在对应字段时自动返回NA,不跳过当前商户条目。
修正后的可运行代码:
library(rvest) library(tidyverse) url <- "https://www.yellowpages.com.au/search/listings?clue=plumbers&locationClue=Greater+Sydney%2C+NSW&lat=&lon=&selectedViewMode=list" testscrape <- function(){ webpage <- read_html(url) # 拆分所有独立商户块 listing_blocks <- webpage %>% html_nodes(".listing") # 逐块提取字段,缺失自动补NA docname <- listing_blocks %>% map_chr(~html_text2(html_node(.x, ".left .listing-name")), .default = NA_character_) ph_no <- listing_blocks %>% map_chr(~html_text2(html_node(.x, ".contact-phone .contact-text")), .default = NA_character_) email <- listing_blocks %>% map_chr(~{ raw_href <- html_attr(html_node(.x, ".contact-email"), "href") ifelse( is.na(raw_href), NA_character_, raw_href %>% str_remove_all(".*:") %>% str_remove_all("\\?(.*)") %>% str_replace_all("%40","@") ) }, .default = NA_character_) tibble(docname = docname, ph_no = ph_no, email = email) }
代码实现注意点:
map_chr设置.default = NA_character_,当当前商户块内找不到电话、邮箱节点时,自动填充字符型NA,不会跳过该条目- 邮箱提取环节单独判断节点是否存在,避免空值参与字符串运算触发报错
- 所有字段均从同一个商户块列表中提取,最终向量长度完全一致,不会出现条目错位
内容的提问来源于stack exchange,提问作者Foothill_trudger
相关产品推荐
相关产品推荐

