【发布时间】:2020-08-25 01:14:56
【问题描述】:
我正在编写代码以使用 asyncio、aiohttp 和 BeautifulSoup 从输入 url 列表中获取一些链接。
这是相关代码的sn-p:
def async_get_jpg_links(links):
def extractLinks(ep_num, html):
soup = bs4.BeautifulSoup(html, 'lxml',
parse_only = bs4.SoupStrainer('article'))
main = soup.findChildren('img')
return ep_num, [img_link.get('data-src') for img_link in main]
async def get_htmllinks(session, ep_num, ep_link):
async with session.get(ep_link) as response:
html_txt = await response.text()
return extractLinks(ep_num, html_txt)
async def get_jpg_links(ep_links):
async with aiohttp.ClientSession() as session:
tasks = [get_htmllinks(session, num, link)
for num, link in enumerate(ep_links, 1)]
return await asyncio.gather(*tasks)
loop = asyncio.get_event_loop()
return loop.run_until_complete(get_jpg_links(links))
我稍后会调用jpgs_links = dict(async_get_jpg_links(hrefs)),其中 hrefs 是一堆链接(约 170 个链接)。
jpgs_links 应该是一个带有数字键和一堆列表作为值的字典。一些值作为空列表返回(应该用数据填充)。当我减少 hrefs 中的链接数量时,更多的列表又满了。
对于下面的照片,我用一分钟的时间重新运行了相同的代码,如您所见,我得到了不同的列表,这些列表返回为空,不同的列表返回为满。
会不会是 asyncio.gather 没有等待所有任务完成?
如何让 asyncio 让我不返回空列表,同时保持 hrefs 中的链接数量高?
【问题讨论】:
-
您确定 URL 每次都以相同的顺序提供吗?
hrefs是如何填充的? -
您是否尝试过添加打印来检查哪些列表是空的,在这种情况下
text是什么。也许您得到了不完整的 HTML 或 BeautifulSoup 出于某种原因无法处理的 HTML。gather不太可能不等待所有任务完成,如果确实如此,您将不会得到一个空列表,您会得到None或异常。除了 asyncio 错误,gather不等待所有任务的唯一原因是如果任务引发异常,但随后该异常将通过get_jpg_links传播到run_until_complete调用。 -
我已将
if not main: print (f'{ep_num} has empty main.')添加到函数extractLinks中,每次运行时都会打印不同的ep_num。那么,我认为是 soup.find_all('img') 返回空列表。你知道如何解决这个问题吗?
标签: python web-scraping beautifulsoup python-asyncio