You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用lxml进行Python网页爬取:Laravel站点登录失败求助

Laravel站点登录爬取失败?试试这几个关键点!

老哥,我之前也踩过Laravel登录爬取的坑,Bitbucket的逻辑相对简单,但Laravel对CSRF防护和会话的处理要严格得多,咱们一步步来解决:

1. 先搞清楚Laravel登录表单的「真实字段」

Laravel默认的登录表单可不是只有账号密码这么简单,你得先抓包看看实际提交的所有字段:

  • 打开浏览器开发者工具(F12),进入Network标签,提交登录,找到POST请求的Form Data:
    • 肯定有_token(你说已经拿到了,但要确认是和当前会话绑定的那个)
    • 可能还有remember(记住我选项,值可能是on或1)
    • 字段名可能不是username,而是email(Laravel默认是邮箱登录)
    • 个别站点会加_method字段(值为POST)

2. 必须用Session保持会话状态

这是最容易忽略的点!requests默认每次请求都是新会话,登录状态根本存不住。你得用requests.Session()来统一管理cookie和会话:

  • 拿CSRF Token的请求、提交登录的请求、后续访问页面的请求,全部用同一个Session实例,不然Laravel会认为你是新用户,直接打回登录页。

3. CSRF Token必须和会话绑定

Laravel的CSRF Token是和当前会话的cookie绑定的,你不能先单独发个GET请求拿token,再用新的POST请求提交——必须用同一个Session先访问登录页,拿到token,紧接着用这个Session提交登录。

修复后的示例代码

import requests
from lxml import html

USERNAME = "你的登录账号"
PASSWORD = "你的登录密码"
LOGIN_PAGE_URL = "Laravel站点的登录页面URL"
TARGET_PAGE_URL = "登录后要访问的页面URL"

# 核心:用Session保持会话
session = requests.Session()

# 第一步:访问登录页,获取CSRF Token和会话cookie
login_response = session.get(LOGIN_PAGE_URL)
tree = html.fromstring(login_response.content)

# 两种方式拿CSRF Token,选适合你的:
# 方式1:从meta标签取(Laravel默认会加这个)
csrf_token = tree.xpath('//meta[@name="csrf-token"]/@content')[0]
# 方式2:从表单隐藏字段取
# csrf_token = tree.xpath('//input[@name="_token"]/@value')[0]

# 第二步:构造登录表单数据,完全对应抓包的字段
login_form_data = {
    "email": USERNAME,  # 改成你抓包看到的字段名,比如"username"
    "password": PASSWORD,
    "_token": csrf_token,
    # 如果抓包有remember字段,加上:
    # "remember": "on"
}

# 第三步:模拟浏览器请求头,避免被拦截
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
    "Referer": LOGIN_PAGE_URL  # 很多站点会验证来源页
}

# 提交登录请求
login_submit_response = session.post(LOGIN_PAGE_URL, data=login_form_data, headers=headers)

# 第四步:验证登录是否成功
result_tree = html.fromstring(login_submit_response.content)
# 比如检查页面是否有登录后的标识(比如用户名、欢迎语)
welcome_element = result_tree.xpath('//span[@class="user-name"]/text()')
if welcome_element:
    print("登录成功!")
    # 现在用session访问目标页面,就能拿到登录后的数据了
    target_response = session.get(TARGET_PAGE_URL)
    print("目标页面内容:", target_response.text[:500])  # 打印前500字符
else:
    print("登录失败,仍在登录页面")
    # 打印响应内容,看看有没有错误提示(比如CSRF令牌无效、密码错误)
    print("错误详情:", login_submit_response.text[:1000])

额外排查点

  • 如果还是失败,打印login_submit_response.text,看看页面有没有明确的错误提示(比如「CSRF令牌不匹配」)
  • 检查是否有验证码:有些Laravel站点会在登录时加验证码,这时候得额外处理验证码识别
  • 确认账号密码确实正确:可以手动登录试试,排除凭证问题

内容的提问来源于stack exchange,提问作者Pure Rhymer Organization

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:45:41