杰瑞科技汇

Python爬虫如何高效提取infobox数据?

“信息框”(Infobox)通常指的是维基百科、百度百科等网站上,位于页面右侧或左侧,包含关键信息的结构化框,它最大的特点是结构化,里面的信息通常以“键-值对”(Key-Value Pair)的形式存在,这使得它非常适合用爬虫来提取。

Python爬虫如何高效提取infobox数据?-图1
(图片来源网络,侵删)

下面我将从原理、工具、实战案例三个方面来为你详细拆解。


爬取 Infobox 的核心原理

无论网站是什么,爬取 Infobox 的基本思路都遵循以下步骤:

  1. 获取网页内容:向目标网址发送 HTTP 请求,获取网页的 HTML 源代码。
  2. 解析 HTML:在 HTML 源代码中,定位到 Infobox 对应的 <div><table> 元素。
  3. 提取数据:在定位到的 Infobox 元素内部,根据其结构规则,提取出所有的“键”和“值”。
  4. 数据清洗与存储:将提取出的数据进行整理(如去除多余的空格、换行),然后以结构化的形式(如字典、JSON、CSV)保存下来。

核心工具库

完成上述任务,Python 生态中有几个非常强大的库:

  1. requests:用于发送 HTTP 请求,获取网页内容,它是 Python 爬虫的“瑞士军刀”,简单易用。
  2. Beautiful Soup:用于解析 HTML 和 XML 文档,它可以将复杂的 HTML 转换成一个 Python 对象,方便我们查找、遍历和修改,这是解析 Infobox 的首选工具
  3. lxml:一个更快的解析器,Beautiful Soup 可以作为它的“前端”使用,通常我们安装 BeautifulSoup4 时会建议同时安装 lxml
  4. pandas:用于数据处理和分析,我们可以很方便地将提取的键值对数据转换为 DataFrame,然后导出为 CSV 或 Excel 文件。

安装命令:

Python爬虫如何高效提取infobox数据?-图2
(图片来源网络,侵删)
pip install requests beautifulsoup4 pandas lxml

实战案例:爬取维基百科“Python (编程语言)”的 Infobox

我们将以维基百科的 Python 词条为例,目标是提取其 Infobox 中的信息,如“创造者”、“首次发布”、“最新稳定版”等。

第 1 步:分析目标 Infobox 的 HTML 结构

在浏览器中打开 Python (programming language) - Wikipedia,然后右键点击 Infobox 中的任意一项,选择“检查”(Inspect)。

你会看到类似这样的 HTML 结构:

关键观察点:

Python爬虫如何高效提取infobox数据?-图3
(图片来源网络,侵删)
  • 整个 Infobox 被包裹在一个 <table> 标签中,并且它有一个很独特的 class 属性:infobox vevent
  • 每一项信息通常由两个 <tr> (table row) 组成,或者一个 <tr> 包含两个 <td> (table data)。
  • 通常在 <th> (table header) 标签内,classinfobox-label
  • 通常在 <td> (table data) 标签内,classinfobox-data

我们的策略就是:

  1. 找到 class="infobox vevent"<table>
  2. 在这个 <table> 中,找到所有 class="infobox-label"<th>class="infobox-data"<td>
  3. 将它们一一对应起来,提取出文本。

第 2 步:编写 Python 代码

下面是完整的代码实现,并附有详细注释。

import requests
from bs4 import BeautifulSoup
import pandas as pd
def scrape_wikipedia_infobox(url):
    """
    爬取维基百科页面中的 Infobox 信息。
    Args:
        url (str): 维基百科页面的 URL。
    Returns:
        dict: 包含 Infobox 键值对的字典。
    """
    # 1. 发送 HTTP 请求获取网页内容
    # 添加 headers 模拟浏览器访问,避免被反爬
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }
    try:
        response = requests.get(url, headers=headers)
        # 如果请求成功 (状态码 200)
        response.raise_for_status() 
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None
    # 2. 使用 BeautifulSoup 解析 HTML
    # 'lxml' 是一个更快的解析器,需要提前安装
    soup = BeautifulSoup(response.text, 'lxml')
    # 3. 定位到 Infobox
    # 通过唯一的 class 'infobox vevent' 来查找
    infobox_table = soup.find('table', class_='infobox vevent')
    # 如果找不到 infobox,则返回空字典
    if not infobox_table:
        print("未找到 Infobox。")
        return {}
    infobox_data = {}
    # 4. 提取键值对
    # find_all() 会查找所有匹配的标签
    # 我们查找所有带有 'infobox-label' 类的 <th> 标签(键)
    labels = infobox_table.find_all('th', class_='infobox-label')
    # 我们查找所有带有 'infobox-data' 类的 <td> 标签(值)
    datas = infobox_table.find_all('td', class_='infobox-data')
    # 理想情况下,键和值的数量应该相等
    if len(labels) != len(datas):
        print("警告:键和值的数量不匹配,提取结果可能不完整。")
        # 可以尝试更健壮的匹配逻辑,但这里为了简单,我们直接一一对应
        # 更健壮的做法是遍历 tr,然后找其中的 th 和 td
        # 这里我们采用一种更通用的方法:遍历所有行
        rows = infobox_table.find_all('tr')
        for row in rows:
            # 键可能在 th 中
            label = row.find('th', class_='infobox-label')
            # 值可能在 td 中
            data = row.find('td', class_='infobox-data')
            if label and data:
                # .get_text(strip=True) 可以获取标签内的文本并去除首尾空格
                key = label.get_text(strip=True)
                value = data.get_text(strip=True)
                infobox_data[key] = value
    else:
        # 如果键值数量匹配,直接按顺序提取
        for label, data in zip(labels, datas):
            key = label.get_text(strip=True)
            value = data.get_text(strip=True)
            infobox_data[key] = value
    return infobox_data
# --- 主程序 ---
if __name__ == "__main__":
    # 目标 URL
    target_url = "https://en.wikipedia.org/wiki/Python_(programming_language)"
    # 调用函数爬取数据
    python_infobox = scrape_wikipedia_infobox(target_url)
    # 5. 数据存储
    if python_infobox:
        print("--- 提取到的 Infobox 数据 ---")
        for key, value in python_infobox.items():
            print(f"{key}: {value}")
        # 使用 pandas 保存为 CSV
        df = pd.DataFrame.from_dict(python_infobox, orient='index', columns=['Value'])
        df.index.name = 'Attribute'
        df.to_csv('python_infobox.csv', encoding='utf-8-sig')
        print("\n数据已成功保存到 python_infobox.csv")

代码解析

  1. requests.get(): 我们发送了一个 GET 请求。headers 参数非常重要,它能模拟浏览器访问,很多网站会检查 User-Agent 来屏蔽简单的爬虫。
  2. response.raise_for_status(): 这是一个好习惯,如果请求失败(404, 500),它会抛出异常,我们可以捕获并处理。
  3. BeautifulSoup(response.text, 'lxml'): 将 requests 获取到的 HTML 文本内容,用 lxml 解析器解析成一个 soup 对象。
  4. soup.find('table', class_='infobox vevent'): 这是核心定位步骤。find() 方法用于查找第一个匹配的元素,我们通过标签名 table 和唯一的 class infobox vevent 来精准地找到 Infobox。
  5. infobox_table.find_all(...): find_all() 会查找所有匹配的元素,返回一个列表,我们用它来找到所有的“键”(<th>)和“值”(<td>)。
  6. .get_text(strip=True): 这是 BeautifulSoup 对象的一个非常有用的方法,它能获取一个标签及其所有子标签中的纯文本,strip=True 会自动去除文本首尾的空白字符,非常方便。
  7. zip(labels, datas): zip 函数可以将两个列表“缝合”在一起,方便我们同时遍历键和值。
  8. pandas 存储: 我们将字典转换成一个 Pandas DataFrame,这是一种表格数据结构,然后调用 .to_csv() 方法轻松地保存为 CSV 文件。encoding='utf-8-sig' 可以确保中文字符在 Excel 中打开时不会乱码。

进阶技巧与注意事项

  1. 健壮性 (Robustness)

    • 网站结构可能会变,上面的代码在键值数量不匹配时有一个备选方案,但更健壮的方式是直接遍历 <tr>,在每个 <tr> 内部寻找 <th><td>,如代码中注释所示的部分。
    • 有些“值”可能包含链接(<a>标签)、图片(<img>标签)或列表(<ul>),如果需要这些信息,需要进一步解析子标签。data.find('a')['href'] 可以提取链接。
  2. 反爬虫机制

    • User-Agent:如上所述,设置一个常见的浏览器 User-Agent。
    • IP 封禁:如果你请求过于频繁,可能会被网站封禁 IP,解决方案是使用代理 IP 池
    • 验证码:对于大型网站,可能会遇到验证码,这需要更高级的技术,如使用 Selenium 或第三方打码平台。
    • 请求频率:在两次请求之间加入短暂的随机延时 (time.sleep(random.uniform(1, 3))),模拟人类行为。
  3. 动态加载内容

    • 有些网站的信息是通过 JavaScript 动态加载的。requests 只能获取初始的 HTML,看不到 JS 渲染后的内容,这时你需要使用 SeleniumPlaywright 等工具来模拟一个真实的浏览器,等待页面加载完成后再获取 HTML。
  4. 不同网站的 Infobox

    • 百度百科:它的 Infobox 通常也是 <table> 结构,但 class 可能是 basicInfo-block 或其他,你需要用同样的方法(浏览器“检查”)去分析它的具体结构,然后修改 find()find_all() 中的参数。
    • 其他网站:原理完全相同,核心在于分析目标网站的 HTML 结构,找到 Infobox 的共同特征(通常是唯一的 idclass),然后编写选择器来定位它。

爬取 Infobox 是爬虫入门的经典实践,因为它目标明确、结构清晰。

核心流程回顾:

  1. 分析:用浏览器开发者工具分析 Infobox 的 HTML 结构,找到其独特的 classid
  2. 请求:使用 requests 库获取网页 HTML。
  3. 解析:使用 BeautifulSoup 库,根据上一步的分析结果,定位到 Infobox 元素。
  4. 提取:在 Infobox 内部,根据 class 或标签名找到所有的“键”和“值”,并用 .get_text() 提取文本。
  5. 存储:使用字典、pandas 等工具将数据整理并保存。

希望这个详细的指南能帮助你掌握 Python 爬取 Infobox 的技能!

分享:
扫描分享到社交APP
上一篇
下一篇