httr::use_proxy与RCurl代理IP轮换行为差异问题排查
httr包GET请求搭配use_proxy时IP不轮换的原因及解决方法
我在调用配置了IP轮换的代理服务器(Smartproxy)时,发现用httr包的GET()+use_proxy()组合请求,每次返回的IP都是固定的;但换用RCurl或系统curl命令,却能正常实现IP轮换。以下是测试代码及结果:
测试代码及结果
httr测试(IP固定)
## usname <- "username" ## uspwd <- "password" ## Ip Sticking library(httr) library(jsonlite) for(idx in 1:3) { message(fromJSON(content(GET("https://ipinfo.io", use_proxy( url = "gate.smartproxy.com", port = 7000, username = usname, password = uspwd )),"text"))$ip) } # output : # 120.188.79.85 # 120.188.79.85 # 120.188.79.85
RCurl测试(IP轮换)
## Ip Rotating library(RCurl) opts <- list( proxy = "gate.smartproxy.com", proxyusername = usname, proxypassword = uspwd, proxyport = 7000 ) options(RCurlOptions = opts) for(idx in 1:3) message(fromJSON(getURL("https://ipinfo.io"))$ip) # output : # 42.118.70.31 # 106.194.152.66 # 180.183.135.201
原因分析
核心差异在于连接复用机制:
- httr基于libcurl实现,默认启用了连接池(connection pooling),会复用同一个HTTP连接发送多次请求。支持IP轮换的代理服务器通常会对同一个连接的请求返回固定IP,不会触发轮换逻辑。
- RCurl的
getURL()默认每次请求都会新建独立连接,代理服务器识别为新请求,因此会返回不同的轮换IP。
解决方案
方案1:禁用连接保持(使用HTTP/1.0)
在GET()请求中添加config(http_version = HTTP_1_0)配置,强制使用HTTP/1.0协议(该协议默认不保持连接),让每次请求都新建连接:
library(httr) library(jsonlite) usname <- "username" uspwd <- "password" for(idx in 1:3) { message(fromJSON(content(GET("https://ipinfo.io", use_proxy( url = "gate.smartproxy.com", port = 7000, username = usname, password = uspwd ), config(http_version = HTTP_1_0) ),"text"))$ip) }
方案2:每次请求使用新的Handle
httr的handle()用于管理连接上下文,每次创建新的handle会强制新建连接,避免复用:
library(httr) library(jsonlite) usname <- "username" uspwd <- "password" for(idx in 1:3) { # 每次循环创建新的handle req_handle <- handle("https://ipinfo.io") message(fromJSON(content(GET(req_handle, use_proxy( url = "gate.smartproxy.com", port = 7000, username = usname, password = uspwd ) ),"text"))$ip) }
内容的提问来源于stack exchange,提问作者anonR
相关产品推荐
相关产品推荐

