最近两周在尝试开发打通BI和前端数据的问题,但由于公司服务器chuncked编码问题一直无法突破,内心非常困扰。最终找我哥大神解决了,改成分次一块块的请求和接收即可解决
方案:
用pycurl来代替requests,但必须将HTTP协议版本设置为1.0,否则与方案2无差别,因为Transfer-Encoding:chunked , Connection:keep-alive 都是HTTP 1.1的新特性,如果将自己的HTTP协议版本设置为1.0,那么服务端将不会再返回chunked,而是以TCP分段的方式直接返回整个文件内容,最后重组成一个完整的HTTP包。
URL:
REFERER:
COOKIE:
提交数据:
post_data = urllib.parse.urlencode({
'down':'0',
})
包头:
headers = [
'Host:xxxxx',
'User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:59.0) Gecko/20100101 Firefox/59.0',
'Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Content-Type:application/x-www-form-urlencoded',
'Accept-Encoding:gzip,deflate',
'Upgrade-Insecure-Requests:1',
'Connection:close'
]
关键代码:
try:
c = pycurl.Curl()
c.setopt(pycurl.URL, URL)
c.setopt(pycurl.REFERER, REFERER)
c.setopt(pycurl.FOLLOWLOCATION, True)
c.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_1_0)
c.setopt(pycurl.CONNECTTIMEOUT, 300)
c.setopt(pycurl.TIMEOUT, 300)
c.setopt(pycurl.ENCODING, 'gzip, deflate')
c.setopt(pycurl.HTTPHEADER, headers)
c.setopt(pycurl.POST, 1)
c.setopt(pycurl.COOKIE,COOKIE)
c.setopt(pycurl.POSTFIELDS, post_data)
b = BytesIO()
c.setopt(c.WRITEFUNCTION, b.write)
c.perform()
except:
raise("post error")
else:
html = b.getvalue().decode("utf-8")
对于HTTP 1.0来讲,如果一次HTTP的响应内容很多,而且又无法提前预知内容的多少,那么就不使用content-length,输出完成后,直接关闭连接即可,一定程度上来讲,content-length对于HTTP 1.0来讲,是可有可无的;通过wireshark抓包来看也是没有Transfer-Encoding:chunked和Content-Length头部的