使用R爬取immobilienscout24.de返回空data.frame问题求助
爬取immobilienscout24.de房产信息返回空DataFrame的解决方案
问题描述
我尝试爬取immobilienscout24.de上的房产信息(包含地址、房间数、价格等),参考R爬虫教程写了代码,但运行后只返回空data.frame(提示“No data available in table”)。试了Stack Overflow上的示例代码,结果同样全是NA,本该获取约120条数据,现在却没有有效内容。以下是测试代码及输出:
第一段测试代码
library("xml2") real_estate <- read_html( "https://www.immobilienscout24.de/Suche/radius/wohnung-kaufen?centerofsearchaddress=Wangels;23758;Testorf;;;geocoordinates=54.24565;10.77587;10.0&sorting=2&enteredFrom=result_list" ) library("rvest") library("magrittr") flats <- real_estate %>% html_nodes(".result-list-entry__data") %>% html_text() flats_df <- data.frame( rooms = gsub(pattern = " room.*", "", flats) %>% as.numeric(), price = gsub(".*€ |.—.*", "", flats) %>% gsub(pattern = ",", replacement = "") %>% as.numeric() )
第二段测试代码
pacman::p_load(rvest, dplyr) real <- data.frame() for(page in seq (from = 1, to = 6, by = 1)){ link <- paste0("https://www.immobilienscout24.de/Suche/de/baden-wuerttemberg/freudenstadt-kreis/wohnung-kaufen?sorting=2&pagenumber=",page) code <- read_html(link) Adresse <- code %>% html_node(".font-normal")%>% html_text() Preis <- code %>% html_node(".result-list-entry__primary-criterion:nth-child(1) .font-highlight")%>% html_text() Qm <- code %>% html_node(".result-list-entry__primary-criterion:nth-child(2) .font-highlight")%>% html_text() Zimmer <- code %>% html_node(".font-tabular .onlyLarge")%>% html_text() real=rbind(real,data.frame( Adresse = ifelse(length(Adresse)==0,NA,Adresse), Preis = ifelse(length(Preis)==0,NA,Preis), Qm = ifelse(length(Qm)==0,NA,Qm), Zimmer = ifelse(length(Zimmer)==0,NA,Zimmer))) write.csv(real, "DatensatzImmobilien.csv") }
输出结果
Adresse Preis Qm Zimmer 1 <NA> <NA> <NA> <NA> 2 <NA> <NA> <NA> <NA> 3 <NA> <NA> <NA> <NA> 4 <NA> <NA> <NA> <NA> 5 <NA> <NA> <NA> <NA> 6 <NA> <NA> <NA> <NA>
问题原因
- 动态内容渲染:immobilienscout24.de的房产列表依赖JavaScript动态加载,
rvest的read_html只能抓取初始静态HTML,无法获取JS渲染后的实际内容。 - 反爬机制:网站会检测请求的User-Agent,非浏览器的请求可能被返回空内容或限制访问,导致目标节点无法被定位。
解决方法
方法1:用RSelenium模拟浏览器抓取(推荐)
RSelenium可以模拟真实浏览器行为,加载动态生成的内容,绕过静态抓取的限制。示例代码:
library(RSelenium) library(rvest) library(dplyr) # 启动Chrome浏览器驱动(需提前下载对应版本的ChromeDriver并配置环境) driver <- rsDriver(browser = "chrome", chromever = "114.0.5735.90") # 替换为你的Chrome版本对应的driver版本 remDr <- driver[["client"]] # 初始化空数据框 real_data <- data.frame() # 遍历分页 for(page in 1:6) { url <- paste0("https://www.immobilienscout24.de/Suche/de/baden-wuerttemberg/freudenstadt-kreis/wohnung-kaufen?sorting=2&pagenumber=", page) remDr$navigate(url) # 等待页面加载(可根据网络情况调整等待时间) Sys.sleep(3) # 获取页面源码 page_source <- remDr$getPageSource()[[1]] page_html <- read_html(page_source) # 定位所有房产条目 entries <- page_html %>% html_nodes(".result-list__listing") # 提取单条房产信息 page_data <- lapply(entries, function(entry) { adresse <- entry %>% html_node(".result-list-entry__address") %>% html_text(trim = TRUE) preis <- entry %>% html_node(".result-list-entry__primary-criterion:nth-child(1) .font-highlight") %>% html_text(trim = TRUE) qm <- entry %>% html_node(".result-list-entry__primary-criterion:nth-child(2) .font-highlight") %>% html_text(trim = TRUE) zimmer <- entry %>% html_node(".font-tabular") %>% html_text(trim = TRUE) data.frame( Adresse = ifelse(is.na(adresse), NA, adresse), Preis = ifelse(is.na(preis), NA, preis), Qm = ifelse(is.na(qm), NA, qm), Zimmer = ifelse(is.na(zimmer), NA, zimmer), stringsAsFactors = FALSE ) }) %>% bind_rows() # 合并数据 real_data <- bind_rows(real_data, page_data) } # 关闭浏览器和驱动 remDr$close() driver$server$stop() # 保存数据 write.csv(real_data, "DatensatzImmobilien.csv", row.names = FALSE) # 查看结果 print(real_data)
方法2:添加请求头伪装浏览器
如果网站仅通过User-Agent限制,可以尝试给请求添加浏览器标识:
library(httr) library(rvest) library(dplyr) real_data <- data.frame() # 设置浏览器请求头 headers <- add_headers( `User-Agent` = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", `Accept-Language` = "de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7" ) for(page in 1:6) { url <- paste0("https://www.immobilienscout24.de/Suche/de/baden-wuerttemberg/freudenstadt-kreis/wohnung-kaufen?sorting=2&pagenumber=", page) # 发送请求 response <- GET(url, headers) page_html <- read_html(content(response, "text")) # 检查是否获取到条目 entries <- page_html %>% html_nodes(".result-list__listing") if(length(entries) == 0) { cat("第", page, "页未获取到数据,可能需要模拟浏览器\n") next } # 提取数据 page_data <- lapply(entries, function(entry) { adresse <- entry %>% html_node(".result-list-entry__address") %>% html_text(trim = TRUE) preis <- entry %>% html_node(".result-list-entry__primary-criterion:nth-child(1) .font-highlight") %>% html_text(trim = TRUE) qm <- entry %>% html_node(".result-list-entry__primary-criterion:nth-child(2) .font-highlight") %>% html_text(trim = TRUE) zimmer <- entry %>% html_node(".font-tabular") %>% html_text(trim = TRUE) data.frame( Adresse = ifelse(is.na(adresse), NA, adresse), Preis = ifelse(is.na(preis), NA, preis), Qm = ifelse(is.na(qm), NA, qm), Zimmer = ifelse(is.na(zimmer), NA, zimmer), stringsAsFactors = FALSE ) }) %>% bind_rows() real_data <- bind_rows(real_data, page_data) } write.csv(real_data, "DatensatzImmobilien.csv", row.names = FALSE) print(real_data)
注意事项
- 爬取前请检查网站的
robots.txt,确保爬取行为符合规则。 - 不要设置过短的请求间隔,建议每页等待2-5秒,避免触发反爬机制。
- RSelenium需要对应浏览器的驱动程序,需提前下载并配置好环境变量(比如ChromeDriver需放在系统PATH中)。
内容的提问来源于stack exchange,提问作者Joschi Nin
相关产品推荐
相关产品推荐

