Python 爬虫的核心流程可拆解为 “发起请求→获取响应→解析数据→存储数据→反爬突破”,不同库对应流程中的不同环节。以下按 “功能分类” 详细解析常用库的定位、作用、关键用法及实战落地,附完整技术选型逻辑:

一、核心基础:HTTP 请求库(发起请求的 “敲门砖”)

爬虫的第一步是向目标服务器发送 HTTP 请求(如 GET/POST),获取页面 HTML 或 API 响应,核心库为 requestsaiohttp

1. requests(同步请求库,爬虫入门首选)
  • 核心定位:Python 生态最流行的同步 HTTP 请求库,封装了底层的 TCP/IP 通信,支持 GET/POST、Cookie、代理、SSL 等所有 HTTP 特性,语法极简。

  • 核心作用:替代 Python 原生的urllib库,解决 “发起请求复杂、代码冗余” 的问题,快速获取静态页面(HTML)或 API 的 JSON 响应。

  • 关键知识点:

    • 基础请求:requests.get(url, params, headers, cookies)(GET 请求带参数)、requests.post(url, data, json)(POST 提交表单 / JSON)。
    • 响应处理:response.text(获取 HTML 文本)、response.json()(解析 JSON 响应)、response.status_code(判断请求是否成功,200 = 成功)。
    • 反爬基础:设置headers(模拟浏览器,如 User-Agent)、proxies(配置代理 IP)、timeout(设置超时避免卡壳)。
  • 实战应用(电商商品列表爬取):

    import requests
    
    # 1. 目标URL(电商商品列表页,带分页参数)
    url = "https://example-mall.com/api/goods"
    params = {"page": 1, "category": "laptop"}  # 分页+分类参数
    # 2. 模拟浏览器请求头(反爬:避免被识别为爬虫)
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/129.0.0.0 Safari/537.36",
        "Referer": "https://example-mall.com/"  # 模拟从首页跳转
    }
    # 3. 发起GET请求
    response = requests.get(url, params=params, headers=headers, timeout=10)
    # 4. 处理响应(若为API,直接解析JSON;若为HTML,交给解析库)
    if response.status_code == 200:
        goods_data = response.json()  # API响应解析为JSON
        print(f"第1页商品数:{len(goods_data['list'])}")
    else:
        print(f"请求失败:{response.status_code}")
    
2. aiohttp(异步请求库,高并发爬取首选)
  • 核心定位:基于asyncio异步 HTTP 请求库,支持 “多请求并发”,解决 requests “同步阻塞”(一次只能发一个请求)的效率问题,适合批量爬取大量 URL(如爬取 100 页商品,异步比同步快 10 倍以上)。

  • 核心作用:在 “高并发场景”(如爬取整站数据、批量检测 URL)中提升效率,避免单线程等待导致的时间浪费。

  • 关键知识点:

    • 语法依赖async/await(Python 异步语法),需用async def定义异步函数。
    • 核心对象:aiohttp.ClientSession()(会话对象,复用 TCP 连接,减少开销)。
    • 避免 “并发过载”:用asyncio.Semaphore控制并发数(如限制 50 个并发,避免压垮目标服务器)。
  • 实战应用(批量爬取 10 页商品 API):

    import aiohttp
    import asyncio
    
    async def fetch_page(session, page):
        """异步获取单页商品数据"""
        url = "https://example-mall.com/api/goods"
        params = {"page": page, "category": "laptop"}
        headers = {"User-Agent": "Mozilla/5.0 ..."}
        async with session.get(url, params=params, headers=headers) as response:
            if response.status == 200:
                return await response.json()  # 异步解析JSON
            return None
    
    async def main():
        """主异步函数:控制并发爬取10页"""
        async with aiohttp.ClientSession() as session:
            # 限制并发数为5(避免被反爬)
            semaphore = asyncio.Semaphore(5)
            # 生成1-10页的任务列表
            tasks = [fetch_page(session, page) for page in range(1, 11)]
            # 并发执行所有任务
            results = await asyncio.gather(*tasks)
            # 处理结果
            for page, result in enumerate(results, 1):
                if result:
                    print(f"第{page}页:{len(result['list'])}个商品")
    
    if __name__ == "__main__":
        asyncio.run(main())  # 启动异步事件循环
    

二、数据解析库(从响应中 “提取宝藏”)

获取响应后(HTML/JSON/ 文本),需提取目标数据(如商品名称、价格、URL),核心工具分 3 类:HTML 解析库(Beautiful Soup、lxml)、正则库(re)、JSON 解析(内置 json 模块)

1. Beautiful Soup(BS4,HTML 解析入门首选)
  • 核心定位HTML/XML 解析库,封装了复杂的 HTML DOM 树遍历逻辑,提供 “人类友好” 的 API(如findfind_all),无需懂 HTML 底层结构,即可快速提取数据。

  • 核心作用:解决 “手动遍历 HTML 标签繁琐” 的问题,适合解析结构相对规整的静态 HTML(如博客、新闻列表、电商商品页)。

  • 关键知识点:

    • 解析器选择:优先用lxml解析器(速度快、容错性强),需先安装lxml库(pip install lxml);次选 Python 内置的html.parser(无需额外安装,速度慢)。
    • 核心方法:
      • soup.find(tag, attrs):提取单个符合条件的标签(如find("div", class_="product-name"),注意class_带下划线,避免与 Python 关键字冲突)。
      • soup.find_all(tag, attrs):提取所有符合条件的标签(返回列表,如find_all("li", class_="product-item"))。
      • 数据提取:tag.text(获取标签内纯文本)、tag["href"](获取标签属性值,如链接)。
  • 实战应用(解析电商商品列表 HTML):

    from bs4 import BeautifulSoup
    import requests
    
    # 1. 用requests获取HTML
    url = "https://example-mall.com/goods/laptop"
    response = requests.get(url, headers={"User-Agent": "Mozilla/5.0 ..."})
    # 2. 用BS4解析HTML(指定lxml解析器)
    soup = BeautifulSoup(response.text, "lxml")
    # 3. 提取所有商品项(li标签,class为product-item)
    product_list = soup.find_all("li", class_="product-item")
    # 4. 遍历提取每个商品的名称和价格
    for product in product_list:
        # 提取商品名称(h3标签,class为product-name)
        name = product.find("h3", class_="product-name").text.strip()
        # 提取商品价格(span标签,class为current-price)
        price = product.find("span", class_="current-price").text.strip()
        # 提取商品链接(a标签的href属性)
        link = product.find("a")["href"]
        print(f"名称:{name} | 价格:{price} | 链接:{link}")
    
2. lxml(高性能 HTML 解析库,xpath 核心依赖)
  • 核心定位高性能 HTML/XML 解析库(C 语言编写),速度是 Beautiful Soup 的 5-10 倍,同时支持XPath 语法(一种强大的 XML/HTML 路径查询语言),适合解析复杂结构或大规模 HTML。

  • 核心作用:解决 “BS4 速度慢” 和 “复杂标签层级提取难” 的问题,尤其适合需要精准定位深层标签的场景(如//div[@id="main"]/ul/li/div[2]/span)。

  • 关键知识点:

    • XPath 语法:用路径表达式定位标签,核心规则:
      • //:从根节点开始,匹配所有符合条件的标签(不考虑层级)。
      • @:获取标签属性(如//a/@href获取所有 a 标签的 href 属性)。
      • text():获取标签内文本(如//h3/text()获取所有 h3 标签的文本)。
      • 条件筛选://div[@class="product-item" and @data-id="123"](匹配 class 为 product-item 且 data-id 为 123 的 div)。
    • lxml 用法:etree.HTML(html_text)将 HTML 文本转为可 xpath 查询的对象,tree.xpath(xpath_expr)执行查询(返回列表)。
  • 实战应用(用 xpath 提取商品数据):

    from lxml import etree
    import requests
    
    # 1. 获取HTML
    url = "https://example-mall.com/goods/laptop"
    response = requests.get(url, headers={"User-Agent": "Mozilla/5.0 ..."})
    # 2. 转为lxml可解析的对象
    tree = etree.HTML(response.text)
    # 3. 用xpath提取所有商品的名称、价格、链接
    names = tree.xpath('//li[@class="product-item"]/h3/text()')  # 商品名称
    prices = tree.xpath('//li[@class="product-item"]//span[@class="current-price"]/text()')  # 价格
    links = tree.xpath('//li[@class="product-item"]/a/@href')  # 链接
    # 4. 打包输出
    for name, price, link in zip(names, prices, links):
        print(f"名称:{name.strip()} | 价格:{price.strip()} | 链接:{link}")
    
3. re(正则表达式库,复杂文本提取工具)
  • 核心定位:Python 内置的正则表达式库,用于匹配 “有固定格式的文本”(如 IP 地址、手机号、URL、提取 HTML 中隐藏的接口地址),不依赖 HTML 结构,适合 “非结构化文本” 或 “HTML 解析库无法处理的场景”。

  • 核心作用:解决 “HTML 解析库无法提取非标签内的文本” 问题,如从 JavaScript 代码中提取接口 URL(如var apiUrl = "https://example.com/api";)、从日志中提取 IP 地址。

  • 关键知识点:

    • 核心方法:
      • re.compile(pattern):编译正则表达式(重复使用时提升效率)。
      • re.findall(pattern, text):提取所有符合 pattern 的文本(返回列表)。
      • re.search(pattern, text):匹配第一个符合条件的文本(返回 match 对象,需用group()获取值)。
    • 常用 pattern 示例:
      • 提取 URL:r'https?://[^\s"\']+'
      • 提取 IP:r'\b(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b'
  • 实战应用(从 JS 代码中提取 API 地址):

    import re
    import requests
    
    # 1. 获取包含JS代码的HTML
    url = "https://example-mall.com/goods/laptop"
    response = requests.get(url, headers={"User-Agent": "Mozilla/5.0 ..."})
    # 2. 用正则提取JS中的API地址(假设API格式为var api = "https://xxx/api/goods?page=1")
    api_pattern = re.compile(r'var apiUrl = "([^"]+)"')  # 捕获双引号内的URL
    api_url = re.search(api_pattern, response.text).group(1)  # 提取第一个匹配的API
    print(f"提取到的API地址:{api_url}")
    # 3. 用API地址直接请求数据(比解析HTML更高效)
    api_response = requests.get(api_url, headers={"User-Agent": "Mozilla/5.0 ..."})
    print(f"API返回数据:{api_response.json()}")
    

三、动态页面处理:Selenium(自动化浏览器,突破 JS 渲染)

  • 核心定位自动化测试工具,可模拟真实浏览器(Chrome、Firefox)的行为(如打开页面、点击按钮、输入文本、滚动页面),解决 “requests 无法执行 JavaScript” 的问题(如 SPA 单页应用、动态加载数据的页面)。

  • 核心作用:处理 “动态渲染页面”(如 Vue/React 项目、需要登录后加载的数据、点击 “加载更多” 才能获取的列表),本质是 “用代码控制浏览器”,获取浏览器渲染后的完整 HTML。

  • 关键知识点:

    • 环境依赖:需下载对应浏览器的驱动(如 Chrome 对应 chromedriver,版本需与浏览器一致),或用webdriver-manager自动管理驱动。
    • 核心操作:
      • 启动浏览器:webdriver.Chrome()(默认打开可视化浏览器),options.add_argument("--headless=new")(无头模式,无界面,适合服务器运行)。
      • 页面操作:driver.get(url)(打开 URL)、driver.find_element(By.XPATH, xpath)(定位元素)、element.click()(点击)、element.send_keys(text)(输入文本)。
      • 数据提取:driver.page_source(获取渲染后的完整 HTML,可交给 BS4 或 lxml 解析)。
  • 实战应用(爬取动态加载的商品列表):

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.chrome.options import Options
    from bs4 import BeautifulSoup
    import time
    
    # 1. 配置Chrome选项(无头模式,提升速度)
    chrome_options = Options()
    chrome_options.add_argument("--headless=new")  # 无头模式
    chrome_options.add_argument("--user-agent=Mozilla/5.0 ...")  # 模拟浏览器UA
    # 2. 启动浏览器
    driver = webdriver.Chrome(options=chrome_options)
    try:
        # 3. 打开目标页面
        driver.get("https://example-mall.com/goods/laptop")
        # 4. 模拟滚动页面(触发动态加载,加载更多商品)
        for _ in range(3):  # 滚动3次,每次等待2秒
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")  # 滚动到底部
            time.sleep(2)  # 等待数据加载
        # 5. 获取渲染后的完整HTML,用BS4解析
        soup = BeautifulSoup(driver.page_source, "lxml")
        product_list = soup.find_all("li", class_="product-item")
        # 6. 提取数据
        for product in product_list:
            name = product.find("h3", class_="product-name").text.strip()
            price = product.find("span", class_="current-price").text.strip()
            print(f"名称:{name} | 价格:{price}")
    finally:
        driver.quit()  # 关闭浏览器,释放资源
    

四、数据存储库(爬取后 “存好宝藏”)

提取数据后需持久化存储(避免内存丢失),核心库为 pandas(Excel/CSV)、sqlite3(轻量数据库)、MongoDB(NoSQL 数据库)

1. pandas(数据处理 + Excel/CSV 存储,轻量首选)
  • 核心定位数据处理库,但自带便捷的文件存储功能,支持将列表 / 字典数据快速写入 Excel(.xlsx)或 CSV(.csv),适合小规模数据(万级以内)的存储与后续分析。

  • 核心作用:解决 “手动拼接 Excel/CSV 繁琐” 的问题,尤其适合需要后续用 Excel 分析的数据(如电商商品价格对比、新闻关键词统计)。

  • 实战应用(将商品数据存入 Excel):

    import pandas as pd
    import requests
    from bs4 import BeautifulSoup
    
    # 1. 爬取商品数据(省略请求和解析步骤,直接构造数据列表)
    goods_data = []
    url = "https://example-mall.com/goods/laptop"
    response = requests.get(url, headers={"User-Agent": "Mozilla/5.0 ..."})
    soup = BeautifulSoup(response.text, "lxml")
    for product in soup.find_all("li", class_="product-item"):
        goods_data.append({
            "商品名称": product.find("h3", class_="product-name").text.strip(),
            "价格": product.find("span", class_="current-price").text.strip(),
            "链接": product.find("a")["href"]
        })
    # 2. 用pandas存入Excel
    df = pd.DataFrame(goods_data)  # 将列表转为DataFrame
    df.to_excel("电商商品列表.xlsx", index=False, engine="openpyxl")  # 写入Excel,不保留索引
    print("数据已存入:电商商品列表.xlsx")
    
2. MongoDB(NoSQL 数据库,大规模 / 非结构化数据首选)
  • 核心定位文档型 NoSQL 数据库,存储格式为 JSON-like(BSON),无需预先定义表结构,适合存储大规模、结构不固定的数据(如爬取的新闻正文、商品评论、多字段嵌套数据)。

  • 核心作用:解决 “Excel/CSV 无法存储大规模数据” 和 “数据结构多变” 的问题(如部分商品有 “折扣价”,部分没有,MongoDB 可灵活存储)。

  • 实战应用(将商品数据存入 MongoDB):

    from pymongo import MongoClient
    import requests
    from bs4 import BeautifulSoup
    
    # 1. 连接MongoDB(默认本地连接,端口27017)
    client = MongoClient("mongodb://localhost:27017/")
    # 2. 创建/选择数据库(名为spider_db)
    db = client["spider_db"]
    # 3. 创建/选择集合(类似表,名为goods_collection)
    collection = db["goods_collection"]
    # 4. 爬取商品数据
    goods_data = []
    url = "https://example-mall.com/goods/laptop"
    response = requests.get(url, headers={"User-Agent": "Mozilla/5.0 ..."})
    soup = BeautifulSoup(response.text, "lxml")
    for product in soup.find_all("li", class_="product-item"):
        goods_data.append({
            "商品名称": product.find("h3", class_="product-name").text.strip(),
            "价格": product.find("span", class_="current-price").text.strip(),
            "链接": product.find("a")["href"],
            "爬取时间": pd.Timestamp.now()  # 新增爬取时间字段
        })
    # 5. 插入数据(insert_many插入多条,insert_one插入单条)
    if goods_data:
        collection.insert_many(goods_data)
        print(f"成功插入 {len(goods_data)} 条数据到MongoDB")
    

五、实战选型策略(避坑指南)

  1. 请求库选型
    • 小规模爬取(<100 页):用requests(简单、无需异步)。
    • 大规模爬取(>100 页):用aiohttp(异步提升效率),配合Semaphore控制并发。
    • 动态页面:先用Chrome开发者工具(F12)分析是否有 API 接口(Network→XHR),有则用requests/aiohttp直接请求 API(效率高),无则用Selenium(万不得已才用,性能消耗大)。
  2. 解析库选型
    • HTML 结构规整:优先用lxml+xpath(速度快、定位精准)。
    • HTML 结构混乱 / 入门学习:用Beautiful Soup(语法友好)。
    • 非标签文本(如 JS 代码、日志):用re(正则匹配)。
    • 绝对避免:用re解析完整 HTML(HTML 结构灵活,正则易出错,维护成本高)。
  3. 存储库选型
    • 数据量小(<1 万条)+ 需 Excel 分析:用pandas存 Excel/CSV。
    • 数据量大(>1 万条)+ 结构多变:用MongoDB
    • 需 SQL 查询(如按价格筛选商品):用sqlite3(轻量)或MySQL(大规模)。

六、总结

Python 爬虫的核心是 “工具链组合”,不同库对应不同环节:

  • 发起请求:requests(同步)、aiohttp(异步)。
  • 解析数据:Beautiful Soup(HTML 入门)、lxml(HTML 高性能 + xpath)、re(复杂文本)。
  • 动态处理:Selenium(浏览器自动化)。
  • 存储数据:pandas(Excel/CSV)、MongoDB(大规模 NoSQL)。

实战中需先分析目标页面(静态 / 动态、是否有 API),再选择最优工具组合,避免 “一把锤子敲所有钉子”(如明明有 API 却用 Selenium 爬取,浪费资源)。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐