首页 > 解决方案 > 当用户名和密码元素 ID 不固定时,使用请求登录站点

问题描述

我正在尝试抓取一个网络论坛,但无法访问登录后的页面。检查登录页面的元素,我发现每次刷新页面时,用户名和密码输入元素的 ID 都会发生变化。我目前的策略是

  1. 创建和使用请求会话
  2. 对论坛登录页面发出 GET 请求
  3. 使用 BeautifulSoup 提取用户名和密码输入元素的 ID
  4. 使用提取的 ID 作为键,我的帐户用户名和密码作为值,用于传递到登录页面的 POST 请求的有效负载字典
  5. 对论坛页面发出 GET 请求

我在第4步遇到了一个问题:POST请求的状态码是400,说明我做错了。

这是一个 MWE,其中的变量KIWIFARMS_USERNAMEKIWIFARMS_PASSWORD已更改为不是我的实际帐户用户名和密码:

import os

import requests
from bs4 import BeautifulSoup

# login url for forum, and fake forum credentials (they're real in my script)
LOGIN_URL = 'https://kiwifarms.net/login/'
KIWIFARMS_USERNAME = 'username'
KIWIFARMS_PASSWORD = 'password'

with requests.Session( ) as session:

  # step 1
  r = session.get( LOGIN_URL )

  # step 2
  soup = BeautifulSoup( r.content, 'lxml' )

  # step 3
  username_id = soup.find( 'input', { 'autocomplete' : 'username' } )[ 'id' ]
  password_id = soup.find( 'input', { 'type' : 'password' } )[ 'id' ]

  payload = {
    username_id: KIWIFARMS_USERNAME,
    password_id : KIWIFARMS_PASSWORD }

  # step 4
  post = session.post( LOGIN_URL, data = payload )

  # failure of step 4 (prints 400)
  print( post.status_code )

我查看了很多页面和链接,包括thisthisthisthis,但我仍然无法弄清楚为什么我的发布请求会收到 400 Bad Request 错误。

我有一个在 Selenium 中工作的版本,但我真的很想知道我正在犯的错误并使用 Requests 让它工作。任何帮助将不胜感激。

标签: pythonweb-scrapingbeautifulsouppython-requests

解决方案


该网站在登录期间生成一个_xfToken,您也错过了一些Form-Data请求POST

在这里,我维护了session使用requests.Session(),然后在我的请求期间解析了valueof ,然后通过请求传递了它。_xfTokenGETPOST

import requests
from bs4 import BeautifulSoup


def Main():
    with requests.Session() as req:
        r = req.get("https://kiwifarms.net/login/login")
        soup = BeautifulSoup(r.text, 'html.parser')
        token = soup.find("input", {'name': '_xfToken'}).get("value")
        data = {
            'username': 'test',
            'password': 'test',
            'remember': '1',
            '_xfRedirect': '/',
            '_xfToken': token
        }
        r = req.post("https://kiwifarms.net/login/login", data=data)
        print(r)


Main()

输出:

<Response [200]>

如果您检查一下r.text,您会发现我们走在正确的轨道上。

<div class="blockMessage blockMessage--error blockMessage--iconic">
The requested user could not be found.
</div>

这是确认我们做得正确,因为我没有通过有效的用户/通行证。


推荐阅读