MST

星途 面试题库

面试题:网络编程之Python异步IO与多线程基础协同

在Python中,当使用异步IO(asyncio)与多线程进行协同工作时,假设你要开发一个简单的网络爬虫程序,需要从多个网页获取数据。请简述如何利用异步IO和多线程来提高爬虫效率,并写出关键代码片段实现从多个URL异步获取网页内容,同时使用多线程来处理获取到的内容(例如解析HTML)。
12.2万 热度难度
后端开发网络编程

知识考点

AI 面试

面试题答案

一键面试

利用异步IO和多线程提高爬虫效率的方法

  1. 异步IO获取网页内容:使用asyncio库来并发地发起网络请求获取网页内容。asyncio基于事件循环机制,能在等待I/O操作(如网络请求)完成时,切换到其他任务,从而避免线程阻塞,提高I/O效率。
  2. 多线程处理内容:获取到网页内容后,由于解析HTML等操作可能是CPU密集型任务,使用多线程可以利用多核CPU的优势,提高处理效率。

关键代码片段

import asyncio
import aiohttp
import threading
from bs4 import BeautifulSoup


async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()


async def fetch_all(urls):
    async with aiohttp.ClientSession() as session:
        tasks = [fetch(session, url) for url in urls]
        return await asyncio.gather(*tasks)


def process_html(html):
    soup = BeautifulSoup(html, 'html.parser')
    # 这里进行具体的HTML解析操作,例如提取标题
    title = soup.title.string if soup.title else 'No title'
    print(f'Processed title: {title}')


def process_in_threads(html_list):
    threads = []
    for html in html_list:
        t = threading.Thread(target=process_html, args=(html,))
        threads.append(t)
        t.start()
    for t in threads:
        t.join()


urls = [
    'http://example.com',
    'http://example.org',
    'http://example.net'
]

loop = asyncio.get_event_loop()
htmls = loop.run_until_complete(fetch_all(urls))
process_in_threads(htmls)

在上述代码中:

  • fetch函数使用aiohttp异步获取单个URL的网页内容。
  • fetch_all函数并发地获取多个URL的内容。
  • process_html函数负责解析HTML,这里简单示例提取标题。
  • process_in_threads函数使用多线程来处理获取到的HTML内容。