如何用R的httr2爬取密码保护的wg-gesucht.de并获取会话消息
爬取密码保护页面的通用流程
你的思路基本准确,标准流程如下:
- 初始化会话(如
html_session):维持会话上下文,自动管理Cookie,确保请求间的状态延续 - 访问登录页面:获取页面中隐藏的必要参数(如CSRF Token、表单专属字段)
- 构造登录请求:填充账号密码,同时带上所有从页面提取的必填参数
- 提交登录请求:通过响应状态、跳转页面内容验证登录是否成功
- 访问目标页面:利用已登录的会话请求需要权限的页面,提取所需数据
本示例中正确提交表单的方法及两种方式对比
正确提交表单的步骤
直接模拟浏览器的表单提交流程,先获取完整表单再填充提交:
library(rvest) library(httr2) wg_site <- "https://www.wg-gesucht.de" # 初始化会话 session <- html_session(wg_site) # 跳转到登录页面(站点登录入口通常在/login.html) login_page <- session %>% jump_to(paste0(wg_site, "/login.html")) # 提取页面中的登录表单(需确认表单索引,若有多个表单需调整[[1]]) login_form <- html_form(login_page)[[1]] # 填充账号密码 filled_form <- set_values(login_form, login_email_username = wg_id, login_password = wg_pw) # 提交表单,获取已登录会话 logged_session <- submit_form(session, filled_form) # 验证登录并提取消息 messages_page <- logged_session %>% jump_to(paste0(wg_site, "/nachrichten.html")) messages_page %>% html_nodes("#main_column > div.row.my40 > div > div > div > div") %>% html_text() %>% gsub(" ","", .) %>% gsub("\n"," ", .)
表单提交vs API端点的选择
- 表单提交:完全模拟浏览器行为,反爬检测概率低,无需额外抓包分析,适合快速实现
- API请求:数据返回格式更规整(多为JSON),解析效率更高,但需要抓包定位真实接口、确认所有请求参数与头信息,对反爬规避要求更高
针对wg-gesucht.de,优先选择表单提交,因为站点登录逻辑基于传统表单,模拟成本更低。
通过JSON方式完成登录的方法
- 定位真实API端点:用浏览器开发者工具(F12)的「网络」面板,监控登录操作的POST请求,确认目标接口为
/ajax/sessions.php?action=login - 提取必要Token:在登录页面的HTML(如meta标签、内嵌script)中找到登录所需的Token(如CSRF Token),需抓包确认参数名
- 构造JSON请求:带上账号密码、Token,设置符合站点要求的请求头,示例代码如下:
library(rvest) library(httr2) wg_site <- "https://www.wg-gesucht.de" # 初始化会话获取基础Cookie与Token session <- html_session(wg_site) login_page <- session %>% jump_to(paste0(wg_site, "/login.html")) # 提取CSRF Token(需根据页面实际结构调整选择器) csrf_token <- login_page %>% html_node("meta[name='csrf-token']") %>% html_attr("content") # 构造登录请求 login_resp <- request(wg_site) %>% req_url_path_append("/ajax/sessions.php") %>% req_url_query(action = "login") %>% req_headers( "Content-Type" = "application/json", "X-Requested-With" = "XMLHttpRequest", "Referer" = paste0(wg_site, "/login.html"), "Cookie" = paste0(session$cookies$name, "=", session$cookies$value, collapse = "; ") ) %>% req_body_json(list( login_email_username = wg_id, login_password = wg_pw, csrf_token = csrf_token # 替换为实际抓包得到的Token参数名 )) %>% req_perform() # 更新会话Cookie,维持登录状态 resp_cookies <- resp_cookies(login_resp) session$cookies <- resp_cookies # 访问消息页并提取数据 messages_page <- session %>% jump_to(paste0(wg_site, "/nachrichten.html")) messages_page %>% html_nodes("#main_column > div.row.my40 > div > div > div > div") %>% html_text() %>% gsub(" ","", .) %>% gsub("\n"," ", .)
注意:站点的Token参数名可能不是csrf_token,需通过抓包确认;部分反爬严格的场景可能需要添加更多请求头(如User-Agent)模拟真实浏览器。
内容的提问来源于stack exchange,提问作者desebast
相关产品推荐
相关产品推荐

