【问题标题】:Is python requests missing something that is present in curl?python请求是否缺少curl中存在的东西?
【发布时间】:2022-01-12 05:53:15
【问题描述】:

所以我有这个 api 我正在尝试使用 python 自动化。我已经在 php curl 中完成了它,它工作得很好。 api没有证书,所以我在php中使用了CURLOPT_SSL_VERIFYPEER, false,这很好用。然而 Python 请求也看到了这个证书问题,所以我在做一个发布请求时使用了verify=False。当我使用 python 向登录 url 发送一个 post 请求时,问题就出现了。服务器返回 404 响应,表示服务器上不存在请求的 url。这是我的php代码

<?php

function post($url,$post,$header){
    $ch=curl_init();
    curl_setopt_array($ch,array(
        CURLOPT_URL => $url,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POSTFIELDS => $post,
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_PORT => 3456,
        CURLOPT_HTTPHEADER => $header,
    ));
    return json_decode(curl_exec($ch));
    curl_close($ch);
}

function login($m, $p){
    $ua = array("Connection:keep-alive","User-Agent:Mozilla/5.0 (Linux; Android 10; M2006C3LG Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36","Content-Type:application/x-www-form-urlencoded; charset=UTF-8","Accept-Encoding:gzip, deflate");
    $data = "email=".$m."&password=".$p."";
    $login = post("https://aartre.com/user/login",$data,$ua);
    print_r($login);
}

$mail = "email@gmail.com";
$pass = "password";
login($mail, $pass);

?>

此 php 代码返回在登录期间分配的令牌,这意味着它正在工作。

这是我的python代码

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning

s = requests.Session()


requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

headers = {
    "Host":"aartre.com:3456",
    "Connection":"keep-alive",
    "User-Agent":"Mozilla/5.0 (Linux; Android 10; M2006C3LG Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36",
    "Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",
    "Accept-Encoding":"gzip, deflate"
}

def get(url):
    return s.get(url, headers=headers, verify=False)

def post(url, data):
    return s.post(url, data=data, headers=headers, verify=False)

def login(email, password):
    url = "https://aartre.com/user/login"
    data = "email={email}&password={password}"
    res = post(url, data)
    print(res.text)

email = "email@gmail.com"
password = 'password'

login(email, password)

正如我所见,此代码没有任何错误。登录 url 也是正确的,与 php.ini 中使用的相同。但是运行之后。这是回复

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
<hr>
<address>Apache/2.4.48 (Win64) OpenSSL/1.1.1l PHP/7.3.30 Server at aartre.com Port 3456</address>
</body></html>

可能是什么问题?我做错了吗?

【问题讨论】:

  • 您确定您的data 正确吗?你在那里的方式使它看起来像电子邮件和密码是 URL 参数的一部分,这绝对不是登录的定义方式。你可以试试这个:data={'email': email, 'password': password} 另外,这可能不是问题。由于某种原因,该 URL 似乎不可用。
  • url 可用,post 请求采用表单数据而不是 json
  • 问题出在登录网址上。该 url 仅不适用于 python 吗?因为如果您尝试上面的 php 代码,它可以正常工作。但是使用python然后它说找不到

标签: python php python-requests php-curl


【解决方案1】:

您已指定 CURL CURLOPT_PORT =&gt; 3456。根据文档:

此选项将 number 设置为要连接的远程端口号,而不是 URL 中指定的端口号或所用协议的默认端口。

所以 CURL 真的没有神奇的能力。等效的 Python requests 将在 URL 中显式指定端口。正如@whiplash 指出的那样,POST 数据应该是dict

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning

s = requests.Session()


requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

headers = {
    "Host":"aartre.com:3456",
    "Connection":"keep-alive",
    "User-Agent":"Mozilla/5.0 (Linux; Android 10; M2006C3LG Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36",
    "Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",
    "Accept-Encoding":"gzip, deflate"
}

def get(url):
    return s.get(url, headers=headers, verify=False)

def post(url, data):
    return s.post(url, data=data, headers=headers, verify=False)

def login(email, password):
    url = "https://aartre.com:3456/user/login"
    data = {'email': email, 'password': password}
    res = post(url, data=data)
    print(res.text)

email = "email@gmail.com"
password = 'password'

login(email, password)

请注意,我认为返回的响应是 JSON 字符串,因此您可以考虑打印 res.json() 而不是 res.text

更新

由于您使用的是 Session 实例,因此更通常的做法是在 Session 实例本身中为每个请求设置您想要使用的任何标头,这样您就不需要在每个实例上显式指定标头请求:

import requests

from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


def login(email, password):
    url = "https://aartre.com:3456/user/login"
    data = {'email': email, 'password': password}
    res = s.post(url, data=data, verify=False)
    result = res.json()
    print(result)


with requests.Session() as s:
    headers = {
        "Connection":"keep-alive",
        "User-Agent":"Mozilla/5.0 (Linux; Android 10; M2006C3LG Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36",
        "Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",
        "Accept-Encoding":"gzip, deflate"
    }

    s.headers.update(headers)

    email = "email@gmail.com"
    password = 'password'

    login(email, password)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 2011-07-14
    • 2013-03-10
    • 1970-01-01
    相关资源
    最近更新 更多