R网页爬取报错:行数不匹配,无法突破YellowPages第60页限制
爬取YellowPages披萨店数据时的60页限制问题
我使用R语言开发,此前从Stack Overflow的问题中学会了爬取YellowPages上加拿大披萨店的名称和地址,单页爬取代码如下:
library(tidyverse) library(rvest) scraper <- function(url) { page <- url %>% read_html() tibble( name = page %>% html_elements(".jsListingName") %>% html_text2(), address = page %>% html_elements(".listing__address--full") %>% html_text2() ) }
随后编写循环尝试爬取全部391页数据:
a = "https://www.yellowpages.ca/search/si/" b = "/pizza/Canada" list_results = list() for (i in 1:391) { url_i = paste0(a,i,b) s_i = data.frame(scraper(url_i)) ss_i = data.frame(i,s_i) print(ss_i) list_results[[i]] <- ss_i } final = do.call(rbind.data.frame, list_results)
遇到的问题
爬取到第60页时出现报错:
Error in data.frame(i, s_i) : arguments imply differing number of rows: 1, 0 In addition: Warning message: In for (i in seq_along(specs)) { : closing unused connection
手动查看第60页发现无法点击进入下一页,想了解这是YellowPages的内部限制,还是有其他方式突破该限制?
原因分析
这是YellowPages的反爬机制设置的内部限制:
- 平台为保护服务器资源和数据权益,会设置分页访问上限,60页就是当前的访问阈值。
- 当爬取到第60页后,服务器返回的页面无任何商家数据(
s_i为0行),和你要合并的页码i(1行)行数不匹配,因此触发报错。
可行解决思路
添加请求延迟
在循环中加入随机延迟,模拟人类浏览间隔,降低被反爬识别的概率。同时增加数据非空判断,避免行数不匹配报错:list_results = list() for (i in 1:391) { url_i = paste0(a,i,b) # 添加2-5秒随机延迟 Sys.sleep(runif(1, 2, 5)) s_i = data.frame(scraper(url_i)) # 仅当有数据时才合并存储 if(nrow(s_i) > 0){ ss_i = data.frame(page = i, s_i) list_results[[i]] <- ss_i } print(paste("完成第", i, "页爬取")) } final = do.call(rbind.data.frame, list_results)异常捕获优化
用tryCatch包裹爬取逻辑,即使某一页失败也不会中断整个循环:scraper_safe <- function(url) { tryCatch({ page <- url %>% read_html() tibble( name = page %>% html_elements(".jsListingName") %>% html_text2(), address = page %>% html_elements(".listing__address--full") %>% html_text2() ) }, error = function(e) { message(paste("第", url, "页爬取失败:", e$message)) return(tibble(name = character(), address = character())) }) }后续循环中调用
scraper_safe替代原scraper即可。切换代理IP
频繁从同一IP访问易被限制,切换不同代理IP可规避IP层面的封锁,但需注意代理的稳定性与合法性。核对Robots协议
先查看YellowPages的robots.txt文件,确认允许爬取的范围和规则,避免违反网站规定引发风险。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

