使用R语言爬虫时修改UA仍遇403错误的解决方法
按优先级从易到难逐步排查:
补全缺失的必要请求头
电商站点的WAF防护不会只校验User-Agent字段,正常Chrome浏览器访问页面时会携带十余个固定请求头,缺失关键字段会被直接判定为爬虫。你当前代码仅传了UA标识,至少要补全以下头信息:Accept:客户端支持的内容类型,普通页面请求可传text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language:语言偏好,针对新西兰站点可传en-NZ,en;q=0.9Sec-Fetch-*系列请求头:Chrome默认会携带Sec-Fetch-Dest、Sec-Fetch-Mode、Sec-Fetch-Site、Sec-Fetch-User字段,多数反爬规则会校验这组字段Upgrade-Insecure-Requests:值设为1
修复会话Cookie逻辑
你当前的代码每次发起请求都是全新独立会话,不会携带站点下发的Cookie。Pak'nSave这类站点首次访问时会下发定位、反爬校验类的初始Cookie,跳过首页直接请求商品页、没有合法Cookie的请求会直接返回403。正确流程是先建立持久化会话访问首页,拿到完整Cookie后再请求商品页,参考实现代码:library(rvest) library(httr) library(dplyr) # 建立持久化会话,自动维护全链路Cookie sess <- html_session( "https://www.paknsave.co.nz/", user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"), add_headers( Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", `Accept-Language` = "en-NZ,en;q=0.9", `Sec-Fetch-Dest` = "document", `Sec-Fetch-Mode` = "navigate", `Sec-Fetch-User` = "?1", `Upgrade-Insecure-Requests` = "1" ) ) # 模拟用户首页停留行为,避免请求过快被识别 Sys.sleep(2) # 跳转请求目标商品页 page <- sess %>% jump_to("https://www.paknsave.co.nz/shop/product/5031015_ea_000pns?name=size-7-eggs") # 打印返回状态码验证结果 print(status_code(page$response))注意:你原代码里调用
GET()函数但没有加载httr包,本身存在函数调用问题,上面的示例用html_session做统一会话管理,不需要单独调用GET方法。排查JS反爬校验
如果补全请求头、携带会话Cookie后仍然返回403,大概率是被WAF的JS挑战拦截了。这类拦截会在首次访问时返回一段JS计算逻辑,浏览器自动执行后生成校验Cookie才会放行,纯HTTP静态请求无法自动执行JS逻辑。
排查方法:打开浏览器开发者工具的网络面板,正常访问站点拿到合法的完整Cookie,把Cookie加到请求头里测试,如果能正常返回200就说明是JS校验拦截。这种场景下可以用chromote包直接调用本地Chrome发起请求,完全模拟真实浏览器的JS执行能力,绕过这类校验。排查IP层面拦截
- 如果你用的是机房服务器IP、公共代理IP、非新西兰本地IP,访问这类本地商超站点大概率会被直接拦截,更换为新西兰本地家庭网络IP即可恢复。
- 如果短时间内请求频率过高,会被临时封禁IP,把请求间隔调整到3秒以上,等待一段时间后再试即可。
爬取站点内容前请确认目标站点的robots规则与服务条款,控制请求频率不要对站点正常服务造成影响。
内容的提问来源于stack exchange,提问作者versb

