简体   繁体   English

curl -u和python请求之间有区别吗

[英]is there a difference between curl -u and python requests

So there's a web page that I want to retreive with python.Requests 因此,有一个我想使用python.Requests检索的python.Requests

https://ororo.tv/api/v2/episodes/9 https://ororo.tv/api/v2/episodes/9

which requires basic authentication. 需要基本身份验证。 If I do it with curl like this 如果我像这样卷曲

 curl -u test@example.com:password https://ororo.tv/api/v2/episodes/9

I get the response I want, however, when trying to do the same in python with Requests library, like this 但是,当尝试使用Requests库在python中执行相同操作时,我得到了想要的响应,像这样

>>> r = requests.get('https://ororo.tv/api/v2/episodes/9', auth=('test@example.com', 'password'))
>>> r
<Response [520]>

I always get 520 response. 我总是得到520响应。 Could someone tell me, what i could be doing wrong ? 有人可以告诉我,我可能做错了什么?

Yes, there are subtle differences. 是的,有细微的差别。 There are slight differences in the headers being sent, and those apparently matter to this API. 发送的标头中存在细微的差异,这些差异显然与此API有关。

If you change the URL queried to use http://httpbin.org/get (an end-point of the online HTTP test service HTTPBin.org , you can see the differences in what curl and requests send: 如果更改查询使用http://httpbin.org/get的URL(在线HTTP测试服务HTTPBin.org的端点) ,则可以看到curlrequests发送内容的不同:

$ curl -u test@example.com:password http://httpbin.org/get
{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Authorization": "Basic dGVzdEBleGFtcGxlLmNvbTpwYXNzd29yZA==",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.51.0"
  },
  "origin": "84.92.98.170",
  "url": "http://httpbin.org/get"
}
$ python -c "import requests; print(requests.get('http://httpbin.org/get', auth=('test@example.com', 'password')).text)"
{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Authorization": "Basic dGVzdEBleGFtcGxlLmNvbTpwYXNzd29yZA==",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.11.1"
  },
  "origin": "84.92.98.170",
  "url": "http://httpbin.org/get"
}

To highlight the differences: 要突出区别:

  • requests sends one extra header, Accept-Encoding , set to gzip, deflate requests发送一个额外的标头Accept-Encoding ,设置为gzip, deflate
  • The User-Agent header differs; User-Agent标头有所不同; both reflect the current agent. 两者都反映了当前的代理商。

You'd have to see which one of these headers causes the issue on the https://ororo.tv/api/v2 site. 您必须在https://ororo.tv/api/v2网站上查看这些标题中的哪一个导致了该问题。 When I correct the URL to use v2 and https , like the curl command, and set the User-Agent header then I get a valid response: 当我更正URL以使用v2https (例如curl命令) 设置User-Agent标头时,我得到一个有效的响应:

>>> headers = {'User-Agent': 'curl/7.51.0'}
>>> r = requests.get('https://ororo.tv/api/v1/episodes/9',
                     auth=('test@example.com', 'password'), headers=headers)
>>> r
<Response [200]>
>>> from pprint import pprint
>>> pprint(r.json())
{'airdate': '2005-10-13',
 'download_url': 'https://static-uk2.ororo.tv/uploads/video/file/9/Everybody.Hates.Chris.S01E04.DVDRip.Everybody.Hates.Sausage_1480525209.mp4?attachment=true&wmsAuthSign=aWQ9ODAzNDI3Kyt2aWRlbys5JnNlcnZlcl90aW1lPTIvOC8yMDE3IDI6Mjc6MDQgUE0maGFzaF92YWx1ZT1kbEpGM3c1bldSOXBOMUg5V2N1S0NnPT0mdmFsaWRtaW51dGVzPTk2MCZzdHJtX2xlbj05NQ%3D%3D',
 'id': 9,
 'name': 'Everybody Hates Sausage',
 'number': '4',
 'plot': 'When Julius buys a big crate of sausage, he makes everyone eat it '
         'with every meal. But Tonya refuses to, causing friction between the '
         'her and Rochelle. While at school, Chris is sentenced to 3 days of '
         'detention after a rumor goes round about him beating up the school '
         'bully, Joey.',
 'resolution': 'SD',
 'season': 1,
 'show_name': 'Everybody hates Chris',
 'subtitles': [{'lang': 'en',
                'url': 'https://uploads.ororo-mirror.tv/uploads/subtitle/file/4867/Everybody.Hates.Chris.S01E04.DVDRip.Everybody.Hates.Sausage.eng.vtt'},
               {'lang': 'ru',
                'url': 'https://uploads.ororo-mirror.tv/uploads/subtitle/file/28629/Everybody.Hates.Chris.S01E04.DVDRip.Everybody.Hates.Sausage.vtt'},
               {'lang': 'es',
                'url': 'https://uploads.ororo-mirror.tv/uploads/subtitle/file/55744/1x04_EH_Sausage.vtt'},
               {'lang': 'pt',
                'url': 'https://uploads.ororo-mirror.tv/uploads/subtitle/file/124429/Everybody_Hates_Chris_104_-_Everybody_Hates_Sausage.vtt'},
               {'lang': 'cs',
                'url': 'https://uploads.ororo-mirror.tv/uploads/subtitle/file/217213/Everybody_Hates_Chris_104_-_Everybody_Hates_Sausages.vtt'},
               {'lang': 'tr',
                'url': 'https://uploads.ororo-mirror.tv/uploads/subtitle/file/192405/Everybody_Hates_Chris_S01E04_-_Everybody_Hates_Sausages-tur.vtt'}],
 'updated_at': 1480640069,
 'url': 'https://static-gra.ororo.tv/uploads/video/file/9/Everybody.Hates.Chris.S01E04.DVDRip.Everybody.Hates.Sausage_1480525209.smil/playlist.m3u8?wmsAuthSign=aWQ9ODAzNDI3Kyt2aWRlbys5JnNlcnZlcl90aW1lPTIvOC8yMDE3IDI6Mjc6MDQgUE0maGFzaF92YWx1ZT1FajlGK2JPMEd3aU1Lc3lnN1M4NlpBPT0mdmFsaWRtaW51dGVzPTk2MCZzdHJtX2xlbj05Ng%3D%3D'}

It's possible that the api you're trying to use requires you to format your request in a specific way, possibly requiring headers and base64 encoded authentication, when using something like Python's requests. 当使用类似Python的请求时,您尝试使用的api可能要求您以特定的方式格式化请求,可能需要标头和base64编码的身份验证。

Check out this example, which will show you how to both send a base64 encoded authentication header, along with some data: 看看这个例子,它将向您展示如何同时发送base64编码的身份验证标头和一些数据:

import requests
import base64

username = "some_username"
password = "some_password"

request_url = "https://ororo.tv/api/v2/episodes/9"

# In this example, I'm passing some data along with the request.
# these are generally what you would expect to pass along in an encoded url:
# /api?some_url_param_key=some_url_param_value

data = {}
data["some_url_param_key"] = "some_url_param_value"

# This is an example header, not necessarily what you need, 
# but it should serve as a good starting point.

headers = {}
headers["Authorization"] = "Basic " + base64.encodestring(username + ":" + password).replace('\n', '')
headers["Accept"] = "*/*"
headers["Content-Type"] = "application/x-www-form-urlencoded"
headers["User-Agent"] = "runscope/0.1"

# You can use post() in some cases where you would expect to use get().
# Every API is its own unique snowflake and expects different inputs.
# Try opening up the Chrome console and run the request in the 
# browser, where you know it works. Examine the headers and response
# in cases where the API you're accessing doesn't provide you 
# with the necessary inputs. 

result = requests.post(request_url, headers=headers, data=data)
print result

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM