You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

从维基百科爬取名人种族信息的技术实现需求

针对900万演员维基百科种族信息爬取的解决方案

针对你要处理900万演员维基百科种族信息的研究需求,这里分享一套高效、合规的实现方案——毕竟量级这么大,得兼顾性能和准确性:

核心思路

  1. 优先用维基百科API而非网页爬取:API更稳定合规,能直接获取结构化数据,避免解析HTML的麻烦,还能降低被反爬限制的风险。
  2. 批量异步处理:900万数据量单线程完全不可行,必须用异步请求+批次处理来提升效率。
  3. 严格匹配预定义种族集合:只从你指定的集合中提取匹配项,避免无关数据干扰研究结果。

具体实现步骤

1. 数据预处理

先对900万演员列表做清洗,减少无效请求:

  • 去重:用集合或数据库去重,避免重复查询同一个演员。
  • 标准化名字格式:统一大小写、去掉冗余后缀(如Jr.III)、修正拼写错误(可借助模糊匹配工具提前处理),提升维基百科API的匹配准确率。

2. 维基百科API数据获取

使用MediaWiki官方API来获取演员页面的infobox信息(维基百科人物页的infobox通常包含ethnicity字段):

  • 核心API接口:https://en.wikipedia.org/w/api.php
  • 关键参数:
    • action=query:指定查询操作
    • titles=演员名字:要查询的页面标题
    • prop=infoboxes:获取页面的infobox数据
    • format=json:返回JSON格式的结构化数据

3. 种族信息提取与匹配

从API返回的infobox中提取ethnicity字段内容,再与你的预定义种族集合做匹配:

  • 提取逻辑:遍历infobox的字段,找到nameethnicity(不区分大小写)的字段,取出其value值。
  • 匹配逻辑:将提取的种族文本与预定义集合做模糊匹配(比如忽略大小写、处理复合种族如Italian-American时匹配集合中的ItalianAmerican),只保留集合内的项。

4. 批量异步与性能优化

  • 异步请求:用Python的aiohttp库实现异步HTTP请求,同时控制并发数(建议每秒不超过50次,符合维基百科API的Rate Limit要求)。
  • 本地缓存:用Redis或本地数据库缓存已查询过的演员结果,避免重复请求。
  • 分批处理:将900万列表分成每批次1000-5000个演员,分批异步处理,同时将结果写入数据库(如PostgreSQL、SQLite),防止程序中断丢失数据。

示例代码片段(Python)

import aiohttp
import asyncio
from typing import List, Dict

# 你的预定义种族集合
PREDEFINED_ETHNICITIES = ['American', 'GreaterEuropean', 'British', 'WestEuropean', 'Italian']

async def fetch_actor_ethnicity(session: aiohttp.ClientSession, actor_name: str) -> List[str]:
    """单个演员的种族信息查询与匹配"""
    api_url = "https://en.wikipedia.org/w/api.php"
    params = {
        "action": "query",
        "titles": actor_name,
        "prop": "infoboxes",
        "format": "json",
        "formatversion": 2  # 使用更简洁的JSON格式
    }
    
    async with session.get(url=api_url, params=params) as resp:
        if resp.status != 200:
            return []
        
        data = await resp.json()
        pages = data.get("query", {}).get("pages", [])
        if not pages or pages[0].get("missing"):
            return []  # 未找到对应页面
        
        # 遍历infobox字段找ethnicity
        infoboxes = pages[0].get("infoboxes", [])
        for infobox in infoboxes:
            for field in infobox.get("fields", []):
                if field.get("name", "").lower() == "ethnicity":
                    ethnicity_text = field.get("value", "").lower()
                    # 匹配预定义种族集合
                    matched_eth = [
                        eth for eth in PREDEFINED_ETHNICITIES
                        if eth.lower() in ethnicity_text
                    ]
                    return list(set(matched_eth))  # 去重
        return []

async def process_actor_batch(actor_names: List[str]) -> Dict[str, List[str]]:
    """处理一批演员的种族查询"""
    # 设置合规的User-Agent,标明你的项目信息
    headers = {"User-Agent": "EthnicityResearchProject/1.0 (your-research-email@example.com)"}
    async with aiohttp.ClientSession(headers=headers) as session:
        tasks = [fetch_actor_ethnicity(session, name) for name in actor_names]
        results = await asyncio.gather(*tasks)
        return dict(zip(actor_names, results))

# 测试示例
async def main():
    sample_actors = ['Chris Hemsworth', 'Paul Walker', 'Al Pacino']
    batch_result = await process_actor_batch(sample_actors)
    for actor, eth in batch_result.items():
        print(f"{actor}: {eth if eth else '未找到匹配种族'}")

if __name__ == "__main__":
    asyncio.run(main())

关键注意事项

  • 合规性:维基百科API允许非商业研究使用,但必须设置清晰的User-Agent,不要超过请求频率限制(可参考维基百科API文档的Rate Limit规则)。
  • 数据准确性:部分演员页面可能没有种族信息,或信息模糊,这类数据建议标记为“未知”;对于复合种族(如Irish-American),需根据你的研究需求决定是否匹配多个预定义项。
  • 错误处理:添加请求超时、重试机制,处理API返回的错误状态码,避免程序因个别请求失败而中断。

内容的提问来源于stack exchange,提问作者Shivam

火山引擎 最新活动