代码之家  ›  专栏  ›  技术社区  ›  showkey

使用cookie---urllib.error发送帖子请求时遇到问题。HTTP错误:HTTP错误503:服务不可用

  •  0
  • showkey  · 技术社区  · 5 年前

    检查主机是否允许涂鸦。

    curl  http://www.etnet.com.hk/robots.txt |grep warrants
    Allow: /www/tc/warrants/
    Allow: /www/tc/warrants/realtime/
    Allow: /www/sc/warrants/
    Allow: /www/sc/warrants/realtime/
    Allow: /www/eng/warrants/
    Allow: /www/eng/warrants/realtime/
    Allow: /mobile/tc/warrants/
    

    使用urllib post方法对目标网页进行涂鸦。
    使用cookie---urllib.error发送帖子请求时遇到问题。HTTP错误:HTTP错误503:服务不可用

    send post request with cookie
    我已经用firefox检查了请求头和参数。 request header params
    现在用cookie构造我的帖子请求。

    import urllib.parse
    import urllib.request as req
    import http.cookiejar as cookie
    
    cookie_jar = cookie.CookieJar()
    opener = req.build_opener(req.HTTPCookieProcessor(cookie_jar))
    req.install_opener(opener)
    
    url = "http://www.etnet.com.hk/www/sc/warrants/search_warrant.php"
    params = {
        "underasset":"HSI",
        "buttonsubmit":"搜寻",
        "formaction":"submitted"
    }
    
    headers = {
        'Accept':"text/htmlpplication/xhtml+xmlpplication/xml;q=0.mage/webp,*/*;q=0.8",
        'Accept-Encoding':"gzip, deflate",
        'Accept-Language':"en-US,en;q=0.5",
        'Connection':'keep-alive',
        'Content-Length':'500',
        'Content-Type':'application/x-www-form-urlencoded',
        "Host":"www.etnet.com.hk",
        "Origin":"http://www.etnet.com.hk",
        "Referer":"http://www.etnet.com.hk/www/sc/warrants/search_warrant.php",
        "Upgrade-Insecure-Requests":"1",
        "User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0"
    }
    
    query_string = urllib.parse.urlencode(params)
    data = query_string.encode()
    cookie_req = req.Request(url, headers=headers, data=data,method='POST')
    page = req.urlopen(cookie_req).read()
    

    我在执行上述代码时遇到了一个问题:

    urllib.error.HTTPError: HTTP Error 503: Service Unavailable
    

    请找出我代码中的错误,以及如何修复它? @NicoNing,最后一个问题是计算标头包含的字节数。

    >>> s="""'Accept':'text/htmlpplication/xhtml+xmlpplication/xml;q=0.mage/webp,*/*;q=0.8',\
    ... 'Accept-Encoding':'gzip, deflate',\
    ... 'Accept-Language':'en-US,en;q=0.5',\
    ... 'Connection':'keep-alive',\
    ... 'Content-Type':'application/x-www-form-urlencoded',\
    ... 'Content-Length':'495',\
    ... 'Host':'www.etnet.com.hk',\
    ... 'Origin':'http://www.etnet.com.hk',\
    ... 'Referer':'http://www.etnet.com.hk/www/sc/warrants/search_warrant.php',\
    ... 'Upgrade-Insecure-Requests':'1',\
    ... 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0'"""
    >>> len(s)
    495
    

    使用上述标头无法获得正确的请求,如果我确实在请求的标头中写入了内容长度,如何将值赋值为 Content-Length 那么?

    0 回复  |  直到 5 年前
        1
  •  3
  •   NicoNing    5 年前

    只需删除标题: 'Content-Length':'500'

    实际上,您的请求内容长度不等于500,但您在标头中定义了它,这会使服务器不可用。

    阅读文档: HTTP > HTTP headers > Content-Length

    Content-Length实体标头表示 发送给收件人的实体体(以字节为单位)。

    在您的情况下,如果您坚持使用header Content-Length ,阅读字体文档,了解它的含义。然后答案就来了:

    "Content-Length" : str(len(data))

    
    import urllib.parse
    import urllib.request as req
    import http.cookiejar as cookie
    
    cookie_jar = cookie.CookieJar()
    opener = req.build_opener(req.HTTPCookieProcessor(cookie_jar))
    req.install_opener(opener)
    
    url = "http://www.etnet.com.hk/www/sc/warrants/search_warrant.php"
    params = {
        "underasset":"HSI",
        "buttonsubmit":"搜寻",
        "formaction":"submitted"
    }
    
    query_string = urllib.parse.urlencode(params)
    data = query_string.encode()
    
    headers = {
        'Accept':"text/htmlpplication/xhtml+xmlpplication/xml;q=0.mage/webp,*/*;q=0.8",
        'Accept-Encoding':"gzip, deflate",
        'Accept-Language':"en-US,en;q=0.5",
        'Connection':'keep-alive',
        'Content-Type':'application/x-www-form-urlencoded',
        # 'Content-Length': str(len(data)),    ### optional 
        "Host":"www.etnet.com.hk",
        "Origin":"http://www.etnet.com.hk",
        "Referer":"http://www.etnet.com.hk/www/sc/warrants/search_warrant.php",
        "Upgrade-Insecure-Requests":"1",
        "User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0",
    }
    
    
    cookie_req = req.Request(url, headers=headers, data=data,method='POST')
    resp = req.urlopen(cookie_req)
    print(resp._method, resp.code)  # POST 200
    
    page = resp.read()
    print(page)
    

    建议您了解更多关于http的信息,并注意您设置的所有标头。

        2
  •  1
  •   McLovin    5 年前

    如所述 this 答案,使用 python s requests 模块在处理http请求时更有效。

    您可以按照以下程序获得最终输出。

    import requests
    
    url = "http://www.etnet.com.hk/www/sc/warrants/search_warrant.php"
    params = {
        "underasset":"HSI",
        "buttonsubmit":"搜寻",
        "formaction":"submitted"
    }
    
    out=requests.post(url,data=params)
    
    print(out.text)
    

    我希望这就是你要找的答案。