2015-09-06 51 views
2

这对我来说是非常艰难的一步,我学习如何做低级套接字通信,但我真的很想学习这一点,我来到了一堵墙,我似乎没有能够找到适当的方式。Python sock.recv没有从页面获取所有数据

我怎样才能得到所有的数据?我已经尝试了很多东西,我只是能够得到部分回应。

我想现在的网址是:

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 
+0

如果你想要整个事情,你为什么要求最大64K字节? –

+0

我应该要求的最大值是多少? –

+0

@ryachza以及我已经尝试打印对日志的响应,并且每次与Chrome浏览器上显示的内容相比,响应都会缩短。 –

回答

3

我能够复制的问题,它似乎是在服务器未返回Content-Length头,造成if len(response[..]) > length长度为0。改变这种语句if length > 0 and ...似乎解决它来触发。

为了始终如一地获得回复,我不得不将时间从0.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) 

只rip套接字接收到一个字符串的一切,不要试图去解释它根本就没有。这会给你提供一切的最佳机会。

我绝对认为在这个水平上玩耍是一个很好的学习方式,完全值得时间的每一刻。话虽如此,图书馆通常喜欢这种事情。

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

+0

有没有一种更简单的方法,或更有效的方式来接收所有的页面,没有我上面写的所有条件?它有点感觉像太多的工作。 –

相关问题