python - 使用 requests post 方法登录网站
问题描述
我正在尝试登录该网站:https ://www.blackrock.com/userplatform/signOn
我正在使用以下脚本来执行此操作:
import requests
from bs4 import BeautifulSoup
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:55.0) Gecko/20100101 Firefox/55.0'
}
resp = requests.get('https://www.ishares.com/us/sign-on.saml', headers=headers)
soup_object = BeautifulSoup(resp.text, 'html.parser')
csrf = soup_object.select_one('meta[name="_csrf"]').get('content')
login_data = dict(userName='USERNAME', password='PASSWORD', csrfmiddlewaretoken=csrf)
r = requests.post('https://www.blackrock.com/userplatform/signOn', data=login_data, headers={"Referer": "https://www.blackrock.com"})
但是,当我在邮递员中运行脚本时,它给了我禁止的 403 错误消息。有人可以建议我做错了什么吗?
该网站甚至共享了一个脚本,用于登录他们的门户并下载一些文件。但它是用 perl 编写的。共享该脚本以供参考。但我想用python来做。
use strict;
use File::Basename;
use Getopt::Long;
use WWW::Mechanize;
use URI qw( );
my $thisScript = basename($0);
print "==START $thisScript==\n";
my ($help, $proxy, $username, $password);
my $urlsToBeDownloaded = "file-url-list.txt";
my $url = "https://www.ishares.com/us/sign-on.saml";
usage() if (@ARGV < 2 or ! GetOptions('proxy:s' => \$proxy,
'username=s' => \$username,
'password=s' => \$password)
or defined $help);
if ($username eq "" || $password eq "") {
usage();
}
my $mech = WWW::Mechanize->new();
if($proxy ne ""){
$mech->proxy(['http', 'https'], $proxy);
}
$mech->get($url);
$mech->submit();
my $ctoken = $mech->field('ctoken');
$mech->get($mech->uri());
$mech->submit_form(
form_number => 1,
fields => {
userName => $username,
password => $password,
ctoken => $ctoken
}
);
$mech->submit();
if($mech->content() =~ "sign-out.saml" ){
open (FILE, $urlsToBeDownloaded)or die "Can't open $urlsToBeDownloaded for read: $!";
while (<FILE>) {
chomp;
print "Downloading==>$_ \n";
eval {
$mech->get($_);
$mech->save_content(getFileNameFromUrl($_));
};
if($@){
print "ERROR: Downloading $_. $@\n";
}
}
close (FILE);
} else {
print "ERROR: Invalid email or password. Please try again.\n";
}
print "==END $thisScript==\n";
sub getFileNameFromUrl{
my $uri = URI->new($_[0]);
return ( $uri->path_segments )[-1];
}
sub usage {
print "\nUsage: perl $thisScript --proxy <Set the proxy (OPTIONAL)> --username <User Name> --password <Password> \n\n";
print("Ex: perl $thisScript --proxy \"http://proxyurl\" --username \"testuser\@test.com\" --password \"password\" \n\n");
exit;
}
解决方案
看起来第三个键是_csrf而不是login_data变量中的 csrfmiddlewaretoken :
=>
login_data = dict(userName='USERNAME', password='PASSWORD', _csrf=csrf)
推荐阅读
- tmux - 是否有创建新会话的 tmux 快捷方式?
- r - 用不同类型的缺失替换一系列变量中的 NA
- ios - ObservableObject 正在更新所有视图并导致 SwiftUI 中的菜单关闭
- php - 为什么 DateTimeZone :: listAbbreviations() 和 DateTimeZone :: listIdentifiers () 之间存在不同的时区
- r - 根据条件使一些样本名称唯一
- c# - Cosmos DB 加快读取速度
- javascript - Uncaught UnknownError:无法在“MediaRecorder”上执行“start”:启动 MediaRecorder 时出错
- azure-devops - 从测试计划运行自动化测试给出错误未找到测试源
- sql - 使用项目值作为选择代码的一部分
- django - django-datatable-view==0.9.0 Django 3.1.3:ImportError:无法导入名称'FieldDoesNotExist'