2016-01-20 56 views
0

我想寫一個簡單的爬網程序。但嘗試從服務器讀取響應僅在第一次時返回答案。然後閱讀器停止讀取字節並返回b「。 我試圖寫超時並在寫入後使用drain()。它沒有產生結果。 Wireshark顯示答案來自服務器,但我的程序沒有看到它們。Asyncio套接字讀取器返回空字節

import asyncio 

HOST = '93.184.216.34' 
PORT = 80 
CONCURRENT_CONNECTIONS = 3 

request = 'GET/HTTP/1.1\r\n' \ 
      'Host: example.com\r\n' \ 
      'Content-Type: application/x-www-form-urlencoded\r\n' \ 
      '\r\n'.encode() 


async def smart_read(reader): 
    buffer = b'' 
    while True: 
     response = await reader.read(1024) 
     if not response: 
      break 
     buffer += response 
    return buffer 


async def work(host, port, request): 
    reader, writer = await asyncio.open_connection(host, port) 
    while True: 
     writer.write(request) 
     resp = await smart_read(reader) 
     print(resp) 


tasks = [] 
for _ in range(CONCURRENT_CONNECTIONS): 
    tasks.append(asyncio.ensure_future(work(HOST, PORT, request))) 

loop = asyncio.get_event_loop() 
loop.run_until_complete(asyncio.wait(tasks)) 
loop.close() 
+0

是什麼''work'而TRUE'循環的目的是什麼?刪除它並測試 – kwarunek

+0

爬網程序將在單個連接中發送多個請求。這是例如完成的。在原始代碼中,我使用Queue進行鏈接傳輸。 – CthUlhUzzz

+0

考慮使用['aiohttp'](http://aiohttp.readthedocs.org/)來抓取網頁。 –

回答

0

一旦StreamReader達到EOF,你總是會得到b'',您可以在閱讀器清除_eof標誌,但它的哈克。子類化StreamReader來處理很多請求,似乎是合理的解決方案。

快速 'N' 髒(真的不使用它)

async def work(host, port, request): 
    reader, writer = await asyncio.open_connection(host, port) 
    while True: 
     reader._eof = False # force to read 
     writer.write(request) 
     resp = await smart_read(reader) 
     print(resp)