MST

星途 面试题库

面试题:Python实现高性能网络爬虫

使用Python编写一个高性能的网络爬虫,能够爬取指定网站的所有链接,并提取页面中的文本内容。需要考虑如何处理异步请求、避免IP封禁以及解析复杂的HTML结构,简述你所采用的框架和技术原理。
50.3万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

代码实现

import asyncio
import aiohttp
from bs4 import BeautifulSoup
import re


async def fetch(session, url, semaphore):
    async with semaphore:
        try:
            async with session.get(url) as response:
                if response.status == 200:
                    return await response.text()
                else:
                    print(f"请求 {url} 失败,状态码: {response.status}")
                    return None
        except Exception as e:
            print(f"请求 {url} 时发生错误: {e}")
            return None


async def parse(html, base_url, all_links, semaphore):
    if not html:
        return
    soup = BeautifulSoup(html, 'html.parser')
    # 提取文本内容
    text = soup.get_text()
    print(f"页面 {base_url} 的文本内容: \n{text}\n")
    # 提取链接
    for link in soup.find_all('a', href=True):
        href = link['href']
        if href.startswith('/'):
            full_url = base_url + href
        elif href.startswith('http'):
            full_url = href
        else:
            continue
        if full_url not in all_links:
            all_links.add(full_url)
            asyncio.create_task(fetch_and_parse(session, full_url, all_links, semaphore))


async def fetch_and_parse(session, url, all_links, semaphore):
    html = await fetch(session, url, semaphore)
    await parse(html, url, all_links, semaphore)


async def main(start_url):
    all_links = set([start_url])
    semaphore = asyncio.Semaphore(10)  # 限制并发数
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_and_parse(session, start_url, all_links, semaphore)]
        await asyncio.gather(*tasks)


if __name__ == "__main__":
    start_url = "https://example.com"  # 替换为指定网站
    asyncio.run(main(start_url))


采用的框架和技术原理

  1. 框架
    • aiohttp:用于处理异步HTTP请求。它基于Python的asyncio库,能充分利用异步I/O的优势,在等待网络响应时不阻塞主线程,大大提高爬虫的效率。通过ClientSession管理HTTP会话,使用async with语法进行异步请求操作。
    • BeautifulSoup:用于解析HTML结构。它提供了简洁的API,能方便地定位和提取HTML中的各种元素,如标签、文本等。
  2. 技术原理
    • 异步请求:利用asyncio库实现异步编程。fetch函数通过async with语句发起异步HTTP请求,并等待响应。asyncio.create_task用于创建新的任务,将请求和解析操作并发执行,提高爬取效率。
    • 避免IP封禁
      • 限制并发数:通过asyncio.Semaphore设置并发请求的数量,避免短时间内对目标服务器发起过多请求,减轻服务器压力,降低被封禁的风险。
      • 合理设置请求头:在实际应用中,可以在aiohttp的请求中设置合理的User - Agent等请求头,模拟真实浏览器行为。
    • 解析复杂的HTML结构
      • BeautifulSoup的灵活选择器:使用find_all等方法结合不同的选择器(如标签名、属性等)定位HTML元素。例如,通过find_all('a', href = True)查找所有带有href属性的a标签,提取链接。
      • 处理相对链接:将相对链接转换为绝对链接,确保能够正确访问页面。通过判断链接是否以/http开头,进行相应的处理。