首页 > 解决方案 > urllib.request.Request() 总是以 HTTP 错误 400 问题结束

问题描述

当使用 urllib 中的 Request 对象来获取 URL 时,我总是以 HTTP 错误 400:错误请求结束。

我想创建一个 watch2gether 房间,您可以在其中发布例如 YouTube URL,它会自动创建一个 watch2gether 房间,以便您可以共享视频。如果我尝试这样做:

import json
import urllib.request, urllib.parse
import urllib.response

wurl = "https://w2g.tv/rooms/create.json"

headers = {'Accept': 'application/json',
           'Content-Type': 'application/json'}

items = []
 
body_create = {"w2g_api_key": "TOKEN", "share": " ","bg_color": "#00ff00", "bg_opacity": "50" }

body_update = { "w2g_api_key": "TOKEN","item_url" : " " }

class watch2gether():
    def createroom(self, url : str): 
        body_create['share'] = url
        data = urllib.parse.urlencode(body_create).encode("utf-8")
        req = urllib.request.Request(wurl, data, headers)
        with urllib.request.urlopen(req) as response: 
            source = response.read()
            dict = json.loads(source)
            items.append(dict['streamkey'])
        return items[0]   

    def updateroom(self, url: str): 
            input_url = f"https://w2g.tv/rooms/{items[0]}/sync_update"
            body_update['item_url'] = url
            data = urllib.parse.urlencode(body_update).encode("utf-8")
            urllib.request.urlopen(input_url, data)

s1 = watch2gether()

user_url = str(input("post url to create room: "))
print("hey here is your link https://w2g.tv/rooms/" + s1.createroom(user_url))

new_url = str(input("post link to update room: " ))
s1.updateroom(new_url)

我得到这个回应:

post url to create room: https://www.youtube.com/watch?v=8RJKBNN4dTw
Traceback (most recent call last):
  File "/Users/jannitselekoglou/Desktop/Discordbot/w2g.py", line 47, in <module>
    print("hey here is your link https://w2g.tv/rooms/" + s1.createroom(user_url))
  File "/Users/jannitselekoglou/Desktop/Discordbot/w2g.py", line 27, in createroom
    with urllib.request.urlopen(req, data) as response: 
  File "/Users/jannitselekoglou/miniconda3/lib/python3.9/urllib/request.py", line 214, in urlopen
    return opener.open(url, data, timeout)
  File "/Users/jannitselekoglou/miniconda3/lib/python3.9/urllib/request.py", line 523, in open
    response = meth(req, response)
  File "/Users/jannitselekoglou/miniconda3/lib/python3.9/urllib/request.py", line 632, in http_response
    response = self.parent.error(
  File "/Users/jannitselekoglou/miniconda3/lib/python3.9/urllib/request.py", line 561, in error
    return self._call_chain(*args)
  File "/Users/jannitselekoglou/miniconda3/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
  File "/Users/jannitselekoglou/miniconda3/lib/python3.9/urllib/request.py", line 641, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request

但是,如果我只使用urlopen()方法而不传入标头,它就可以完美地工作。(您可以在此处阅读 Watch2Gether API 文档,非常简短)

我真的不明白我在使用urllib.request.Request()时做错了什么,以及为什么我不需要传入标头,因为 API 文档明确指出你必须这样做“确保设置您对 application/json 的请求的内容类型”

标签: python

解决方案


推荐阅读