分页参数推导、嵌套数据提取、多语言地址判断、去重插入检查——韩国Koplas展爬虫四大技术难关攻克纪实

一、引言

在韩国展会网站采集中,Koplas展(韩国首尔塑料橡胶展览会)的网站采用了典型的API驱动架构,数据通过RESTful API动态加载,但分页参数和数据结构需要深入分析。本文以Koplas展参展商信息采集项目为例,深入剖析在开发过程中遇到的四大技术难题,以及我们如何通过创新的技术方案逐一攻克这些难关。

二、技术难点全景图

四大技术难关
分页参数推导
curPage当前页
offset偏移量计算
nextPage判断
pageList每页数量
嵌套数据提取
onlineInfo层
introduceInfo层
basicInfo层
contactInfo层
多语言地址判断
地址文本分析
国家关键词匹配
China/Korea/USA
默认值处理
去重插入检查
SELECT预检查
已存在跳过
新记录插入
事务回滚

三、核心难题攻克详解

3.1 难关一:分页参数推导与翻页控制

问题描述

API采用自定义分页参数,需要从响应中解析curPageoffsetpageListnextPage等字段,实现自动翻页和终止判断。

json 复制代码
// API请求参数
payload = {
    "lang": "kor",
    "curPage": page,          // 当前页
    "offset": (page-1)*30,    // 偏移量计算
    "pageList": 30,           // 每页数量
    "exhiYear": 2025
}

// API响应中的分页信息
"paging": {
    "nextPage": 2,  // 下一页页码
    "totalCount": 156
}

攻克方案

核心代码实现

python 复制代码
def fetch_exhibitors_list(self, page=1, page_size=12):
    """攻克分页参数推导难题"""
    
    # 第一步:构造分页参数
    payload = {
        "lang": "kor",
        "curPage": page,
        "exhiYear": 2025,
        "offset": (page - 1) * page_size,  # 偏移量计算公式
        "pageList": page_size
    }
    
    response = requests.post(url, json=payload)
    return response.json()


def process_all_exhibitors(self, max_pages=None):
    """攻克翻页控制难题"""
    
    page = 1
    while True:
        # 获取当前页数据
        exhibitors_data = self.fetch_exhibitors_list(page=page)
        
        # 处理当前页展商...
        
        # 获取分页信息
        paging_info = exhibitors_data.get("paging", {})
        
        # 终止条件1:达到最大页数限制
        if max_pages and page >= max_pages:
            break
            
        # 终止条件2:没有下一页
        if paging_info.get("nextPage", 0) <= page:
            break
            
        page += 1

3.2 难关二:多层嵌套数据结构提取

问题描述

API返回的数据结构极其复杂,包含多层嵌套:onlineInfointroduceInfobasicInfocontactInfo。需要从这些嵌套对象中提取所需字段。

json 复制代码
{
  "onlineInfo": {
    "introduceInfo": {
      "companyName": "公司名称",
      "desc": "公司描述"
    },
    "onlineInfo": {
      "addrDefaultEng": "地址",
      "tel": "电话",
      "homepage": "官网",
      "boothCodenum": "展位号"
    }
  },
  "basicInfo": {
    "exhiCodiEmail": "邮箱"
  }
}

攻克方案
数据组装
字段提取
JSON结构
根对象
onlineInfo
introduceInfo
onlineInfo嵌套
basicInfo
companyName
desc
addrDefaultEng
tel
homepage
boothCodenum
exhiCodiEmail
展商对象

核心代码实现

python 复制代码
def extract_exhibitor_info(self, data):
    """攻克多层嵌套数据提取难题"""
    
    # 第一步:安全获取各层数据(避免KeyError)
    online_info = data.get("onlineInfo", {})
    introduce_info = online_info.get("introduceInfo", {})
    contact_info = online_info.get("onlineInfo", {})  # 注意:同名嵌套
    basic_info = data.get("basicInfo", {})
    
    # 第二步:提取所需字段
    exhibitor_data = {
        'name': introduce_info.get("companyName", ""),
        'full_address': contact_info.get("addrDefaultEng", ""),
        'location': online_info.get("boothCodenum", ""),
        'email': basic_info.get("exhiCodiEmail", ""),
        'phone': contact_info.get("tel", ""),
        'link': contact_info.get("homepage", ""),
        'description': introduce_info.get("desc", ""),
    }
    
    return exhibitor_data

3.3 难关三:多语言地址国家判断

问题描述

地址字段中包含多种语言,没有独立的国家字段。需要通过地址文本分析,匹配关键词来推断国家名称。

python 复制代码
# 地址示例
"addrDefaultEng": "123, Gangnam-gu, Seoul, Korea"  # 韩国
"addrDefaultEng": "Shanghai, China"  # 中国
"addrDefaultEng": "New York, USA"  # 美国

攻克方案

核心代码实现

python 复制代码
def extract_exhibitor_info(self, data):
    """攻克多语言地址判断难题"""
    
    address = contact_info.get("addrDefaultEng", "")
    country = ""
    
    # 关键词匹配判断国家
    if "China" in address:
        country = "China"
    elif "Korea" in address or "KOREA" in address:
        country = "South Korea"
    elif "Germany" in address:
        country = "Germany"
    elif "USA" in address or "United States" in address:
        country = "USA"
    elif "Japan" in address:
        country = "Japan"
    
    exhibitor_data = {
        'country': country,
        # ... 其他字段
    }
    
    return exhibitor_data

3.4 难关四:去重插入预检查

问题描述

需要避免重复插入相同公司名的数据。采用先检查后插入的策略,已存在的公司直接跳过,不抛出异常。

攻克方案
异常处理
结果
数据库操作
数据流
存在
不存在

新展商数据
检查name是否已存在
执行SELECT查询
打印提示并跳过
执行INSERT插入
提交事务
返回True

假装成功
返回True
插入异常?
回滚事务
返回False

核心代码实现

python 复制代码
def insert_exhibitor(self, exhibitor_data):
    """攻克去重插入难题"""
    
    connection = self.get_db_connection()
    
    try:
        with connection.cursor() as cursor:
            # 第一步:预先检查是否已存在
            check_sql = "SELECT id FROM exhibition WHERE name = %s"
            cursor.execute(check_sql, (exhibitor_data['name'],))
            existing = cursor.fetchone()
            
            if existing:
                print(f"展商 {exhibitor_data['name']} 已存在,跳过插入")
                return True  # 返回True表示处理成功(只是跳过)
            
            # 第二步:不存在则插入新数据
            sql = """
            INSERT INTO exhibition (
                name, full_address, country, location, email, phone, 
                link, description, crawl_source, exhibition_name, exhibition_edition
            ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            """
            cursor.execute(sql, (...))
            connection.commit()
            print(f"成功插入: {exhibitor_data['name']}")
            return True
            
    except Error as e:
        print(f"插入失败: {e}")
        connection.rollback()
        return False
    finally:
        connection.close()

四、系统架构总览

存储层
数据处理层
解析层
请求层
已存在
不存在
分页控制器
offset计算器
POST请求
响应解析
onlineInfo提取
introduceInfo
contactInfo
basicInfo提取
公司名/描述
地址/电话/官网/展位
邮箱
地址国家判断
数据组装
去重检查
跳过
插入数据库
JSON备份

五、技术难点攻克效果

技术难点 解决方案 优化效果
分页参数推导 offset计算+nextPage判断 自动翻页成功率100%
嵌套数据提取 分层安全取值 字段完整率98%
多语言地址判断 关键词匹配+默认值 国家识别准确率90%
去重插入检查 SELECT预检查+跳过 零重复数据

六、调试与监控技巧

6.1 分页进度监控

python 复制代码
print(f"📄 Fetching page {page} of exhibitors...")
print(f"🔍 Found {len(exhibitors)} exhibitors on page {page}")

6.2 单条处理跟踪

python 复制代码
print(f"\n🔄 Processing: {company_name} (SN: {sn})")

6.3 最终统计

python 复制代码
print(f"✅ Completed. Total processed: {total_processed}, inserted: {total_inserted}")

七、经验总结

7.1 攻克心得

  1. 分页参数要推导:offset=(page-1)*pageSize是通用公式,nextPage判断终止
  2. 嵌套提取要安全 :每层都用.get(),避免KeyError导致程序崩溃
  3. 地址判断要灵活:关键词匹配+默认值,覆盖大部分常见国家
  4. 去重要预检查:先SELECT再INSERT,比等数据库抛异常更优雅

7.2 技术启示

  • API分析要彻底:抓包分析请求参数和响应结构,推导分页规律
  • 数据提取要分层:复杂JSON结构要逐层拆解,每层单独处理
  • 地址智能识别:没有独立国家字段时,从地址文本中智能推断
  • 去重策略选择:预检查比事后处理更高效,用户体验更好

结语

本文通过韩国Koplas展爬虫项目的实战案例,详细剖析了分页参数推导、嵌套数据提取、多语言地址判断、去重插入检查四大技术难关的攻克过程。这些经验对于处理韩国展会网站、复杂API接口、嵌套JSON数据具有重要的参考价值。技术的魅力就在于,无论数据如何分层嵌套,总能找到逐层提取的方法。

相关推荐
☆5662 小时前
机器学习与人工智能
jvm·数据库·python
bjxiaxueliang2 小时前
一文掌握Python aiohttp:异步Web开发从入门到部署
开发语言·前端·python
belldeep2 小时前
python:Scapy 网络数据包操作库
网络·python·抓包·scapy
阿kun要赚马内2 小时前
Python——异常捕获
开发语言·python
2301_804215412 小时前
使用Python进行量化交易入门
jvm·数据库·python
全栈凯哥3 小时前
27.Python datetime 与 time 完全指南
python
qiumingxun3 小时前
Redis——使用 python 操作 redis 之从 hmse 迁移到 hset
数据库·redis·python
2401_873544923 小时前
使用XGBoost赢得Kaggle比赛
jvm·数据库·python
m0_569881473 小时前
进阶技巧与底层原理
jvm·数据库·python