【问题标题】:Asyncio sockets reader returns empty bytes异步套接字读取器返回空字节
【发布时间】:2016-04-26 20:09:59
【问题描述】:

我正在尝试编写一个简单的爬虫。但是尝试从服务器读取响应仅在第一次返回答案。然后阅读器停止读取字节并返回 b''。 我试着在写完后设置一个超时并使用 drain() 。它没有产生结果。 Wireshark 显示答案来自服务器,但我的程序看不到它们。

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()

【问题讨论】:

  • while Truework 中循环的目的是什么?删除它并测试
  • 爬虫将在一个连接中发送许多请求。例如,这是完成的。在原始代码中,我使用Queue进行链接传输。
  • 考虑使用aiohttp 抓取网页。
  • 爬虫示例甚至在 asyncio 示例中 github.com/python/asyncio/blob/master/examples/crawl.py
  • 感谢您的建议。但是为什么我的代码不起作用?

标签: python-3.x python-asyncio python-sockets


【解决方案1】:

一旦StreamReader 到达EOF,你总是会得到b'',你可以在阅读器中清除_eof 标志,但这很hacky。子类化 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多