Python sock.recv没有从页面

时间:2015-09-06 21:26:13

标签: python python-2.7 sockets python-sockets

这对我学习如何进行低级套接字通信是非常困难的一步,但我真的想学习这个,我已经到了墙上,我似乎无法找到合适的方法。 / p>

我如何获取所有数据?我已经尝试过多种能让我得到部分反应的东西。

我正在尝试的网址是:

http://steamcommunity.com/market/search/render/?query=&start=0&count=100&search_descriptions=0&sort_column=price&sort_dir=asc&appid=730&category_730_ItemSet%5B%5D=any&category_730_ProPlayer%5B%5D=any&category_730_TournamentTeam%5B%5D=any&category_730_Weapon%5B%5D=any&category_730_Rarity%5B%5D=tag_Rarity_Ancient_Weapon

经过研究我尝试过这种方式,但仍然无法打印上面的完整JSON页面,我做错了什么?

        sock.send(request)
        response = ""
        first = True
        length = 0
        while True:
            partialResponse = sock.recv(65536)
            if len(partialResponse) != 0:
                #print("all %s" % partialResponse)
                # Extract content length from the first chunk
                if first:
                    startPosition = partialResponse.find("Content-Length")
                    if startPosition != -1:
                        endPosition = partialResponse.find("\r\n", startPosition+1)
                        length = int(partialResponse[startPosition:endPosition].split(" ")[1])
                    first = False
                # add current chunk to entire content
                response += partialResponse
                # remove chunksize from chunck
                startPosition = response.find("\n0000")
                if startPosition != -1:
                    endPosition = response.find("\n", startPosition+1)
                    response = response[0:startPosition-1] + response[endPosition+1:]
                if len(response[response.find("\r\n\r\n")+2:]) > length:
                    break
            else:
                break
        print response

1 个答案:

答案 0 :(得分:3)

我能够复制该问题,似乎服务器没有返回内容长度标头,导致if len(response[..]) > length触发长度为0.将该语句更改为if length > 0 and ...似乎已解决它

我必须将我设置的时间从.3增加到0.5秒,以便始终获得响应。

我在Chrome中收到内容长度,但可能是因为内容编码是gzip。我猜他们没有为未压缩的响应发送内容长度。

this document的Content-Length部分将标题列为“SHOULD”。

其他一般建议:我不会假设第一个块总是包含所有头。确实应该没有开启“第一”。你可能应该阅读,直到你遇到\r\n\r\n信号表示标题完成并单独处理后面的所有内容作为响应主体。

根据评论进行修改:

对于快速和肮脏的事情,我可能会这样做:

response = ''
while True:
    chunk = sock.recv(65536)

    if len(chunk) == 0:
      break
    else:
      response += chunk

pieces = response.split('\r\n\r\n')

headers = pieces[0]
body = '\r\n\r\n'.join(pieces[1:])

print response
print body
print headers

print len(response), len(body), len(headers)

只需将套接字接收的所有内容翻录成字符串,不要试图解释它。这将为您提供获得一切的最佳机会。

我绝对认为在这个级别上玩是一种很好的学习方式,并且完全值得每时每刻都值得。话虽这么说,有一个原因,库通常是这类事情的首选。

HTTP确实没有很多保证 - 它非常灵活,并且有很多变量。所以你需要从基本没有期望/要求开始,并仔细建立不断思考“如果这个/那个”。需要注意的一件事是,分块可以在任何地方发生。在标题完成之前,块可能会中断,甚至可能在\r\n之间断开,这意味着您需要跨块解析以检测边界。对于常见用法,将整个响应读入内存可能不是问题,但当然某些响应或其他要求可能会使这种做法变得不切实际/不可能。