登录页面背后通常藏着两样东西:一个是需登表单提交后的会话凭证,另一个是网站前端 JavaScript 动态生成的加密参数。直接拿 requests 去 POST 用户名密码,爬虫大概率会收到 403 或者一个空页面。需登原因很简单——服务器不认你。网站
我去年帮朋友抓一个论坛的爬虫帖子数据,那个站用的需登是 Discuz,登录接口除了账号密码,网站还带了一个
formhash字段。爬虫这个值藏在登录页的需登 HTML 里,每次刷新都会变。网站你用固定值去提交,爬虫服务器直接拒绝。需登解决办法就是网站先 GET 登录页,用正则或者 lxml 把formhash抠出来,爬虫再带着它去 POST。这是最基础的一层。更麻烦的是那些把登录逻辑放在 JavaScript 里的站。比如某电商平台的商家后台,密码不是明文传输,前端用 RSA 加密,公钥还是动态下发的。你打开 Chrome DevTools,在 Network 面板里找到登录请求,看 Payload 那一栏,密码字段是一长串十六进制。这时候光靠 requests 不够了,得用 Selenium 或者 Playwright 驱动真实浏览器。让浏览器自己去执行 JS,你只管填输入框、点按钮。
from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get("https://example.com/login") driver.find_element(By.ID, "username").send_keys("your_user") driver.find_element(By.ID, "password").send_keys("your_pass") driver.find_element(By.ID, "submit").click() # 之后 driver.get_cookies() 拿到会话用 Selenium 的好处是省心,坏处是慢。每个请求都要等页面渲染,跑几千个页面的时候,时间成本很高。折中方案是先用 Selenium 登录一次,把 cookies 导出来,再交给 requests.Session 去批量抓取。这样既绕过了 JS 加密,又保留了 requests 的速度。
还有一种情况是 token 放在请求头里,比如
Authorization: Bearer xxxxx。这个 token 可能是登录后接口返回的,也可能存在 localStorage 里。你可以在 Selenium 里执行driver.execute_script("return localStorage.getItem('token')")把它取出来。拿到之后,后续请求直接加这个头就行,连 cookies 都不用管。验证码是另一个坎。简单的图形验证码可以用 ddddocr 或者 tesseract 识别,复杂一点的滑块、点选,要么接打码平台,要么用深度学习模型自己训练。我试过用 OpenCV 做滑块缺口识别,准确率大概八成,剩下的两成交给重试机制。点选验证码比较恶心,通常得靠第三方服务,比如超级鹰,一分钱一次,量大也不便宜。
有些站会检测 Selenium。比如 navigator.webdriver 这个属性,正常浏览器是 false,Selenium 驱动的是 true。对策是加
--disable-blink-features=AutomationControlled启动参数,再用 CDP 把 navigator.webdriver 改成 false。还有的站会检查 window.chrome 对象是否存在,那就用 undetected-chromedriver 这个库,它专门做反检测,省得自己一个个补。最后说一个容易被忽略的点:登录后的会话是有有效期的。你抓了半小时,突然全部返回登录页,说明 session 过期了。这时候要么重新登录,要么在代码里加一个检测逻辑——发现响应里包含登录页特征字符串,就自动触发重新登录流程。我一般会在 Session 类里写一个
ensure_login()方法,每次请求前检查一下,过期就重新走一遍登录。说到底,登录爬虫的核心就一句话:让服务器相信你是一个已经登录的正常用户。至于怎么让它相信,手段从简单到复杂,取决于对面站点的防护级别。大部分中小站点,cookies 加请求头就够了。大厂的后台,那就得老老实实上浏览器自动化,甚至得养号、控频、换 IP。没有银弹。
顶: 87踩: 9233






评论专区