Anekys 发表于 2022-1-18 10:40

Python使用httpx异步请求保存至MongoDB报错

代码如下:
import httpx
import logging
import asyncio
import json
from motor.motor_asyncio import AsyncIOMotorClient

LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)
semaphore = asyncio.Semaphore(5)
session = httpx.AsyncClient(http2=True)


async def scrape_api(url):
    async with semaphore:
      # 忽略ssl证书与开启http2.0一致,需要在client提供参数
      try:
            async with httpx.AsyncClient(http2=True) as client:
                r = await client.get(url)
                return r.json()
      except Exception as error:
            logging.log(level=logging.WARNING, msg=f"{url}获取失败,\n原因如下:{error}")


async def get_index(page):
    url = f"https://spa16.scrape.center/api/book/?limit=18&offset={page * 18}"
    return await scrape_api(url)


async def get_detail(id):
    url = f"https://spa16.scrape.center/api/book/{id}/"
    data = await scrape_api(url)
    await save_data(data)


MONGO_CONNECTION_STRING = 'mongodb://localhost:27017'
MONGO_DB_NAME = 'Books'
MONGO_COLLECTION_NAME = 'Books'
MONGO = AsyncIOMotorClient(MONGO_CONNECTION_STRING)
db = MONGO
collection = db


async def save_data(data):
    logging.info('saving data %s', data)
    if data:
      return await collection.update_one({
            'id': data.get('id')
      }, {
            '$set': data
      }, upsert=True)


async def main():
    booklist =
    result = await asyncio.gather(*booklist)
    logging.info('results %s', json.dumps(result, ensure_ascii=False, indent=2))
    ids = []
    for data in result:
      if not data:
            continue
      for bid in data["results"]:
            ids.append(bid.get("id"))
    details =
    await asyncio.wait(details)


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


程序可以正常运行到sava_data函数,并且logging也正常打印,但是最后会报错:
RuntimeError: Task <Task pending name='Task-401' coro=<get_detail() running at E:\code\Python\ScrapeCenter\SPA16\LikeBook.py:32> cb=> got Future <Future pending cb=> attached to a different loop
说不是一个loop,但是如果将httpx换成aiohttp请求的话,就不会有问题。

v.n.lee 发表于 2022-1-18 11:52

可以指定loop不

Anekys 发表于 2022-1-18 12:06

v.n.lee 发表于 2022-1-18 11:52
可以指定loop不

{:1_907:}没看懂,怎么指定?

v.n.lee 发表于 2022-1-18 12:19

我知道aiohttp可以指定loop,httpx没试过。

ynboyinkm 发表于 2022-1-18 12:24

httpx还没有用过!!!

Anekys 发表于 2022-1-18 15:41

v.n.lee 发表于 2022-1-18 12:19
我知道aiohttp可以指定loop,httpx没试过。

因为网站需要http2.0所以需要用httpx:rggrg
页: [1]
查看完整版本: Python使用httpx异步请求保存至MongoDB报错