获取不为空的 asyncio 结果

Get asyncio results not empty

提问人:Roman Kazmin 提问时间:11/18/2023 更新时间:11/18/2023 访问量:26

问:

我在使用 asyncio 进行网页抓取任务时遇到了一些问题。我想在 cian 网站上收集有关房地产经纪人的信息 - 我使用 asyncio,因为在这个网站上使用了分页。我遇到了两个问题。当我使用完全异步方法时,我无法收到请求的信息 - 我收到有关使用过的 VPN 的消息:

async def async_get_all_realtors(session, url):
    async with session.get(url) as response:
        html = await response.text()

    bsobj = soup(html, 'html.parser')
    
    agent_names = []
    for i in bsobj.findAll('div', {'class': '_9400a595a7--name--ipaRv'}):
        agent_names.append(i.span.text.strip())
    
    return agent_names

我做了一些小的改变,比如:

async def async_get_all_realtors(url):
    html = urlopen(url)
    bsobj = soup(html, 'html.parser')
    
    
    agent_names = []
    for i in bsobj.findAll('div', {'class': '_9400a595a7--name--ipaRv'}):
        agent_names.append(i.span.text.strip())
    
    return agent_names

修复后,我可以收到请求的信息。

第二个问题如下 - 我收到空结果,尽管 all_agent_names 变量的转储打印显示所有变量都是 Okey。以下是完整代码:

from urllib.request import urlopen
import aiohttp
from bs4 import BeautifulSoup as soup
import asyncio
import pandas as pd

url = "https://www.cian.ru/realtors/?dealType=sale&offerType%5B0%5D=flat&regionId=1"

def get_num_pages(url):
    html = urlopen(f"{url}&page=1")
    bsobj = soup(html.read(), 'html.parser')
    return int(bsobj.findAll('span', {'class': '_9400a595a7--content--sGuO7'})[-1].text)

async def async_get_all_realtors(url):
    html = urlopen(url)
    bsobj = soup(html, 'html.parser')
    
    
    agent_names = []
    for i in bsobj.findAll('div', {'class': '_9400a595a7--name--ipaRv'}):
        agent_names.append(i.span.text.strip())
    
    return agent_names

async def main(url, num_pages):
    tasks = []

    for page_num in range(1, num_pages + 1):
        page_url = f"{url}&page={page_num}"
        task = asyncio.create_task(async_get_all_realtors(page_url))
        tasks.append(task)

    results = await asyncio.gather(*tasks)

    # Here all are Ok this variable contains full information
    all_agent_names = [name for result in results for name in result]

    print(all_agent_names)
    return all_agent_names


num_of_pages = get_num_pages(url)
result = await main(url, num_of_pages) # Empty result, why?

请帮忙我的错误在哪里?

P.S. 我使用 JupiterNotebook 来运行代码......

网页抓取 python-asyncio

评论


答:

0赞 Andrej Kesely 11/18/2023 #1

下面是一个如何使用 + 的示例:requestsasyncioThreadPoolExecutor

import asyncio
from concurrent.futures import ThreadPoolExecutor

import requests

api_url = "https://api.cian.ru/agent-catalog-search/v1/get-realtors/?dealType=sale&offerType=flat&regionId=1&page={page}&limit=10"


def get_page(page):
    r = requests.get(api_url.format(page=page))
    return r.json()


async def main():
    loop = asyncio.get_running_loop()

    with ThreadPoolExecutor(max_workers=2) as pool:
        tasks = {loop.run_in_executor(pool, get_page, p) for p in range(1, 3)}  # <-- increase number of pages here
        for coro in asyncio.as_completed(tasks):
            result = await coro
            for i in result["items"]:
                print(f'{i["name"]:<40} {i["age"]:<30}')


if __name__ == "__main__":
    asyncio.run(main())

指纹:

Тимур Данилян                            5 лет и 4 мес. на Циан        
Валентина Пугановская                    14 лет и 6 мес. на Циан       
Владимир Щучкин                          5 лет и 4 мес. на Циан        
Егор Загрия                              5 лет и 1 мес. на Циан        
Николай Панин                            2 года и 7 мес. на Циан       
Маргарита Мелешина                       1 год и 5 мес. на Циан        
Катерина Буйнова                         14 лет и 9 мес. на Циан       
Артур Бейдулаев                          13 лет и 3 мес. на Циан       
Виктор Гладких                           7 лет и 6 мес. на Циан        
Елена Закора                             5 лет и 6 мес. на Циан        
Анна Гусева                              4 года и 7 мес. на Циан       
Юлия Маслова                             11 лет и 8 мес. на Циан       
Екатерина Пронина                        12 лет и 5 мес. на Циан       
Юлия Карчемная                           5 лет и 7 мес. на Циан        
Алексей Шебалов                          14 лет и 8 мес. на Циан       
Наталья  Бурова                          17 лет и 11 мес. на Циан      
Татьяна Шиллинг                          7 лет и 11 мес. на Циан       
Ярослав Бибиков                          5 лет и 5 мес. на Циан        
Елена Наумова                            10 мес. на Циан               
Наталья Перескокова                      7 лет и 8 мес. на Циан