python - 使用 python 登录 codeforces (Beautiful Soup and Requests)
问题描述
我最近尝试使用 python 登录 codeforces,但失败了
import pyautogui
import clipboard
import requests
from bs4 import BeautifulSoup
import re
#user_name = input()
#psd = input()
base = "http://codeforces.com"
service_url = "{base}/{login}".format(base=base, login="enter")
dt = requests.get("http://codeforces.com/enter?back=%2F")
dt = dt.text
ss=BeautifulSoup(dt, 'html.parser')
print(ss)
token = ss.find(id='body').find(style = 'position: relative;').findNext(style = 'position: relative;')
token = token.find(id = 'pageContent')
print(token)
token = token.find(**{'class': 'enterPage'})
token = token.find(**{'class': 'roundbox'})
token = token.find('form')
print(token)
csrf_token = token.find(action = "").get('value')
print(csrf_token)
token = token.find(**{'class': 'table-form'})
token = token.find('input')
print(token)
ftaa = token.findNext('input').get('value')
print(ftaa)
bfaa = token.findNext('input').get('value')
print(bfaa)
print(csrf_token, ftaa, bfaa)
usr_name = input()
psd = input()
payload = {
'csrf_token': csrf_token,
'action': 'enter',
#'ftaa': ftaa,
#'bfaa': bfaa,
'handle': usr_name,
'password': psd
}
data = requests.post(service_url, data=payload)
data = data.text
soup = BeautifulSoup(data, 'html.parser')
soup = soup.prettify()
print(soup)
解决方案
我认为您还需要在标题中添加 csrf 令牌
import requests
from bs4 import BeautifulSoup
base = "https://codeforces.com"
service_url = "{base}/{login}".format(base=base, login="enter")
s = requests.session()
dt = s.get(service_url)
dt = dt.text
ss = BeautifulSoup(dt, 'html.parser')
with open("login.html", "w") as file:
file.write(str(ss))
csrf_token = ss.find_all("span", {"class": "csrf-token"})[0]["data-csrf"]
print(csrf_token)
usr_name = input("User name: ")
psd = input("Password: ")
headers = {
'X-Csrf-Token': csrf_token
}
payload = {
'csrf_token': csrf_token,
'action': 'enter',
'handleOrEmail': usr_name,
'password': psd,
}
data = s.post(service_url, data=payload, headers=headers)
data = data.text
soup = BeautifulSoup(data, 'html.parser')
print(soup)
with open("output.html", "w") as file:
file.write(str(soup))
logout = soup.select_one("a[href*=logout]")["href"]
data = s.get(base + logout)
soup = BeautifulSoup(data.text, "html.parser")
with open("logout.html", "w") as file:
file.write(str(soup))
该网站使用以下代码添加它:
$.ajaxSetup({ scriptCharset: "utf-8" ,contentType: "application/x-www-form-urlencoded; charset=UTF-8", headers: {
'X-Csrf-Token': Codeforces.getCsrfToken()
}});
推荐阅读
- pandas - 如何在多个列上进行聚合?
- reactjs - 对于可以为 null 或未定义的 Typescript 值,如何避免 Object 可能为 null
- c# - Kendo MVC 自动完成 UI 无法通过对象
- android - Android setprop:设置属性失败
- r - 如何将计算列添加到源 DataFrame
- reactjs - 如何在材质 ui 中添加我选择的导航链接项目的边框底部?
- c - 关于 gcc 及其输出的 32 位 x86 架构的问题(i386 与 i686)
- javascript - 在 React 中使用来自父状态的默认选项重新渲染选择元素
- java - 对三角形进行排序时快速排序太慢
- python - unixODBC:未找到数据源名称且未指定默认驱动程序,Ubuntu 上的 pyodbc 连接到 SQL Server