Невозможно получить веб-страницу, используя aiohttp ClientSession - PullRequest
0 голосов
/ 03 апреля 2019

Я хотел бы использовать asyncio для получения веб-страницы.

Однако, когда я выполнил приведенный ниже код, страница не была получена.

Код -

import aiofiles
import aiohttp
from aiohttp import ClientSession
import asyncio

async def get_webpage(url, session):
    try:
        res = await session.request(method="GET", url=url)
        html = await res.text(encoding='GB18030')
        return 0, html
    except:
        return 1, []

async def main_get_webpage(urls):
    webpage = []
    connector = aiohttp.TCPConnector(limit=60)       
    async with ClientSession(connector=connector) as session:
        tasks = [get_webpage(url, session) for url in urls]
        result = await asyncio.gather(*tasks)
        for status, data in result:
            print(status)
            if status == 0:
                webpage.append(data)
        return webpage

if __name__ == '__main__':
    urls = ['https://lcdsj.fang.com/house/3120178164/fangjia.htm', 'https://mingliugaoerfuzhuangyuan0551.fang.com/house/2128242324/fangjia.htm']
    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)
    loop = asyncio.get_event_loop()
    webpage =  loop.run_until_complete(main_get_webpage(urls))

Я ожидаю, что в функции будут напечатаны два нуля main_get_webpage(urls).

Однако напечатаны два нуля.

Что не так с моим кодом?

Как исправитьпроблема?

Большое спасибо.

1 Ответ

2 голосов
/ 03 апреля 2019

Что не так с моим кодом?

Что не так в том, что у вас есть try: ... except:, который маскирует источник проблемы. Если вы удалите предложение except, вы увидите сообщение об ошибке, сообщающее об основной проблеме:

UnicodeDecodeError: 'gb18030' codec can't decode byte 0xb7 in position 47676: illegal multibyte sequence

Веб-страница не закодирована как GB18030. Страница объявляет себя как GB2312 (предварительный курсор к GB18030), но использование этого в качестве кодировки также не выполняется.

Как решить проблему?

В зависимости от того, что вы хотите сделать с текстом веб-страницы, у вас есть несколько вариантов:

  1. Найдите поддерживаемую Python кодировку, которая работает со страницей, как указано. Это идеальный вариант, но я не смог найти его с помощью короткого поиска. (Использование этого ответа для выяснения того, что, по мнению Chrome, использует страница, также не помогло, поскольку ответ был GBK, что приводит к ошибке на символе 47676.)

  2. Расшифруйте страницу с помощью более простого обработчика ошибок, такого как res.text(encoding='GB18030', errors='replace'). Это даст вам хорошее приближение текста с неразборчивыми байтами, представленными как символ замены юникода . Это хороший вариант, если вам нужно найти на странице подстроку или проанализировать ее как текст, и вам нет дела до странного символа где-то в нем.

  3. Откажитесь от идеи декодирования страницы в виде текста и просто используйте res.data(), чтобы получить байты. Этот вариант лучше всего подходит, если вам нужно заархивировать или кэшировать страницу или проиндексировать ее.

...