dt/dd表格解析、URL拼接缺失、ON DUPLICATE字段覆盖、CSS选择器定位——俄罗斯轮胎展爬虫四大技术难关攻克纪实

作者:进击的雷神日期:2026/3/8

一、引言

在俄罗斯展会网站采集中,莫斯科轮胎及橡胶展览会(Expocentr)的网站采用了典型的表格布局和dt/dd结构存储展商信息。本文以该展会参展商信息采集项目为例,深入剖析在开发过程中遇到的四大技术难题,以及我们如何通过创新的技术方案逐一攻克这些难关。
在这里插入图片描述

二、技术难点全景图

四大技术难关

dt/dd表格解析

键值对结构

dt/dd配对遍历

字段映射转换

键名规范化

URL拼接缺失

相对路径提取

基础URL缺失

404错误风险

手动拼接修复

ON DUPLICATE字段覆盖

增量更新策略

指定字段更新

updated_at时间戳

数据一致性

CSS选择器定位

tbody tr选择

td索引访问

badge类提取

多级元素嵌套

三、核心难题攻克详解

3.1 难关一:dt/dd键值对表格解析

问题描述
展商详情页使用HTML定义列表(<dl>)结构,信息以<dt>(定义术语)和<dd>(定义描述)的键值对形式存储。需要将这种结构解析为字典,并映射到数据库字段。

1<dl>
2    <dt>Web:</dt>
3    <dd><a href="https://company.ru">www.company.ru</a></dd>
4    
5    <dt>E-mail:</dt>
6    <dd><a href="mailto:info@company.ru">info@company.ru</a></dd>
7    
8    <dt>Address:</dt>
9    <dd>Moscow, Russia</dd>
10    
11    <dt>Phone:</dt>
12    <dd>+7 495 123-45-67</dd>
13</dl>
14

攻克方案
在这里插入图片描述

核心代码实现

1def get_exhibitor_details(detail_url):
2    """攻克dt/dd表格解析难题"""
3    
4    response = requests.get(detail_url)
5    soup = BeautifulSoup(response.text, 'html.parser')
6    
7    details = {}
8    panel = soup.find('div', class_='panel-body')
9    
10    if panel:
11        # 第一步:获取所有dt和dd元素
12        dt_elements = panel.find_all('dt')
13        dd_elements = panel.find_all('dd')
14        
15        # 第二步:zip配对遍历
16        for dt, dd in zip(dt_elements, dd_elements):
17            key = dt.text.strip().replace(':', '').lower()
18            value = dd.text.strip()
19            
20            # 第三步:字段映射和特殊处理
21            if key == 'web':
22                web_link = dd.find('a')
23                if web_link:
24                    value = web_link['href']
25                    details['link'] = value
26            
27            elif key == 'e-mail':
28                email_link = dd.find('a')
29                if email_link:
30                    value = email_link['href'].replace('mailto:', '')
31                    details['email'] = value
32            
33            elif key == 'address':
34                details['full_address'] = value
35            elif key == 'phone':
36                details['phone'] = value
37            elif key == 'description':
38                details['description'] = value
39    
40    return details
41

3.2 难关二:相对URL拼接缺失

问题描述
列表页提取的详情页URL是相对路径(如/en/exhibitors/123),直接访问会导致404错误。需要手动拼接基础URL才能得到完整的可访问地址。

1# 列表页提取的相对路径
2detail_url = "/en/exhibitors/123"
3
4# 需要拼接为基础URL
5base_url = "https://icatalog.expocentr.ru"
6full_url = "https://icatalog.expocentr.ru/en/exhibitors/123"
7

攻克方案

结果

解决方案

问题

相对路径
/en/exhibitors/123

直接请求 → 404

基础URL
https://icatalog.expocentr.ru

手动拼接
C + A

完整URL
https://icatalog.expocentr.ru/en/exhibitors/123

200 OK

核心代码实现

1def get_exhibitors_list():
2    """攻克URL拼接缺失难题"""
3    
4    # 基础URL常量
5    BASE_URL = "https://icatalog.expocentr.ru"
6    
7    for row in rows:
8        name_link = cells[0].find('a')
9        if name_link:
10            # 提取相对路径
11            relative_url = name_link['href']
12            
13            # 手动拼接完整URL
14            full_url = BASE_URL + relative_url
15            
16            exhibitor = {
17                'name': name_link.text.strip(),
18                'detail_url': full_url,  # 存储完整URL
19            }
20    
21    return exhibitors
22

3.3 难关三:ON DUPLICATE字段覆盖策略

问题描述
使用ON DUPLICATE KEY UPDATE进行增量更新时,需要明确指定哪些字段在重复时更新,哪些字段保持不变(如创建时间)。同时要自动更新时间戳。

攻克方案
在这里插入图片描述

核心代码实现

1-- 攻克ON DUPLICATE字段覆盖难题
2INSERT INTO `exhibition1` (
3    `name`, `full_address`, `country`, `location`, `email`, `phone`, 
4    [`link`](https://xplanc.org/primers/document/zh/03.HTML/EX.HTML%20%E5%85%83%E7%B4%A0/EX.link.md), `description`, `crawl_source`, `exhibition_name`, `exhibition_edition`,
5    `created_at`, `updated_at`
6) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
7ON DUPLICATE KEY UPDATE 
8    -- 明确指定需要更新的字段
9    `full_address` = VALUES(`full_address`),
10    `country` = VALUES(`country`),
11    `location` = VALUES(`location`),
12    `email` = VALUES(`email`),
13    `phone` = VALUES(`phone`),
14    [`link`](https://xplanc.org/primers/document/zh/03.HTML/EX.HTML%20%E5%85%83%E7%B4%A0/EX.link.md) = VALUES([`link`](https://xplanc.org/primers/document/zh/03.HTML/EX.HTML%20%E5%85%83%E7%B4%A0/EX.link.md)),
15    `description` = VALUES(`description`),
16    `updated_at` = NOW()  -- 只更新时间戳,created_at保持不变
17

3.4 难关四:CSS选择器精确定位

问题描述
列表页使用复杂的表格结构,需要通过多级CSS选择器精确定位每个字段:tbody tr定位行,td索引访问各列,badge类提取展位号。

1<table>
2    <tbody>
3        <tr>
4            <td><a href="/en/exhibitors/123">公司A</a></td>
5            <td><a href="#">Russia</a></td>
6            <td>...</td>
7            <td><span class="badge">1A-01</span></td>
8        </tr>
9    </tbody>
10</table>
11

攻克方案

在这里插入图片描述

核心代码实现

1def get_exhibitors_list():
2    """攻克CSS选择器精确定位难题"""
3    
4    soup = BeautifulSoup(response.text, 'html.parser')
5    
6    # 第一步:选择所有表格行
7    rows = soup.select('tbody tr')
8    
9    for row in rows:
10        # 第二步:获取所有单元格
11        cells = row.find_all('td')
12        
13        # 第三步:按索引访问各列
14        if len(cells) >= 4:
15            name_link = cells[0].find('a')
16            country_link = cells[1].find('a')
17            # 第四步:查找badge类提取展位
18            location_span = cells[3].find('span', class_='badge')
19            
20            if name_link and country_link and location_span:
21                exhibitor = {
22                    'name': name_link.text.strip(),
23                    'country': country_link.text.strip(),
24                    'location': location_span.text.strip(),
25                    'detail_url': BASE_URL + name_link['href']
26                }
27                exhibitors.append(exhibitor)
28    
29    return exhibitors
30

四、系统架构总览

在这里插入图片描述

五、技术难点攻克效果

技术难点解决方案优化效果
dt/dd表格解析zip配对+字段映射解析成功率100%
URL拼接缺失手动拼接基础URL请求成功率100%
ON DUPLICATE字段覆盖指定更新字段+时间戳数据一致性100%
CSS选择器定位多级选择器+索引访问定位准确率100%

六、调试与监控技巧

6.1 实时进度打印

1print(f"\nProcessing: {exhibitor['name']}")
2print(f"Successfully inserted/updated: {exhibitor_data['name']}")
3

6.2 数据库连接管理

1finally:
2    if connection:
3        connection.close()
4        print("Database connection closed.")
5

6.3 异常处理

1except requests.RequestException as e:
2    print(f"Error fetching exhibitor details: {e}")
3    return {}
4

七、经验总结

7.1 攻克心得

  1. dt/dd要配对:zip遍历键值对,比单独提取更可靠
  2. URL要补全:永远不要假设提取的URL是完整的
  3. 更新要精准:ON DUPLICATE只更新需要更新的字段
  4. 选择器要精准:多级选择器+索引访问,定位万无一失

7.2 技术启示

  • 表格解析有套路:tbody tr + td索引,定位表格数据
  • 相对路径要警惕:看到相对路径立即想到拼接基础URL
  • 增量更新要设计:明确哪些字段更新,哪些字段保留
  • CSS选择器要熟练:多练习各种选择器组合

结语

本文通过俄罗斯轮胎展爬虫项目的实战案例,详细剖析了dt/dd表格解析、URL拼接缺失、ON DUPLICATE字段覆盖、CSS选择器定位四大技术难关的攻克过程。这些经验对于处理俄罗斯展会网站、表格布局、定义列表结构具有重要的参考价值。技术的魅力就在于,无论面对多复杂的HTML结构,总能找到精准的解析方法。


dt/dd表格解析、URL拼接缺失、ON DUPLICATE字段覆盖、CSS选择器定位——俄罗斯轮胎展爬虫四大技术难关攻克纪实》 是转载文章,点击查看原文


相关推荐


三月,我只想做好这四件事
修己xj2026/2/28

今天是二月的最后一天,也是春节后上班第一周的收官之日。 在我们中国人的观念里,只有过完春节,新的一年才算真正开始。往年的这个时候,我总会兴致勃勃地立下一堆flag,制定满满当当的年度计划。虽然年终盘点时发现大部分都没实现,但来年依旧乐此不疲——仿佛只要把计划写得够漂亮,生活就会自动变好。 但今年不一样了。 家里添了一位新成员,我的身份悄然发生了改变。抱着怀里这个两个月大的小家伙,我突然不想再立那些宏大的flag,也不想做那些看似充实却往往落空的计划了。 一年很长,长到要数着日历过365个日夜;


C# WPF canvas中绘制缺陷分布map并实现缩放
zls3653652026/2/19

1、前台xaml 这里把canvas包裹在scrollviewer里面是为了避免滚轮缩放时canvas超出划定的区域,导致显示异常。 2. 后台代码: -. canvas load事件,主要用来获取控件的长度和宽度 -. canvas_mousewheel(object sender,MouseWheelEventArgs e)这个事件主要功能是为了实现通过鼠标进行canvas控件的缩放 -. 这里的逻辑主要为了实现缺陷分布图上的缺陷通过x进行标注 -.深度拷


AI 视觉连载3:RGB与通道
董章鱼是个攻城狮2026/2/11

在2、灰度与色彩的最后,给出了一个由彩色图片转成灰度图的示例,并且通过 color_image.mode获取了图片的格式:彩色图片获取到的格式为 RGBA,灰度图为 L。 这一节再介绍一下 RGB 图片以及通道的概念。 通道这个概念,在 深度学习 中很重要,并且极为重要。 举个例子—— 在很多时候,对AI神经网络中的一些算法做工程化实现,或者做性能优化,除了关注算法本身之外,还会关注数据存储格式。 一般在 pytorch 中(一个AI模型框架),数据的存储格式 NCHW, C指代的就是通道(ch


自组织特征映射(SOM)的数据聚类程序。 matlab程序 数据格式为excel
NBhhbYyOljP2026/2/2

自组织特征映射(SOM)的数据聚类程序。 matlab程序 数据格式为excel。 打开MATLAB准备搞点数据魔法?今天咱们整点有意思的——用自组织特征映射(SOM)给Excel数据自动分群。这玩意儿就像给数据画美食地图,让相似的样本自动抱团取暖。 先来点准备工作。把Excel数据塞进MATLAB最直接的方式就是readtable函数: data = readtable('你的数据.xlsx'); raw_data = table2array(data(:,2:end)); % 假设第


iOS 常用调试工具大全-打造你的调试武器库
sweet丶2026/1/24

还记得你第一次使用NSLog(@"Hello, World!")的时刻吗?那是调试的起点。但随着应用复杂度呈指数级增长,我们需要的工具也经历了革命性进化: 第一代:基础输出(NSLog、print) 第二代:图形化界面(Xcode调试器、Instruments) 第三代:运行时动态调试(FLEX、Lookin) 第四代:智能化监控(性能追踪、自动化检测) 今天,一个成熟的iOS开发者工具箱中,至少需要掌握3-5种核心调试工具,它们就像外科医生的手术刀——精准、高效、各有所长。 一、运行时调试


SpringCloud Gateway 集成 Sentinel 详解 及实现动态监听Nacos规则配置实时更新流控规则
普通网友2026/1/15

目录 一、前言二、版本选择和适配 2.1、本文使用各组件版本2.2、官方推荐版本 三、部署sentinel-dashboard 3.1、下载 sentinel-dashboard jar包3.2、启动 sentinel-dashboard 四、Gateway 集成 Sentinel实现控制台配置流控规则测试 4.1、添加Gateway 集成 Sentinel 包4.2、添加 Gateway 服务启动JVM参数 4.2.1、配置说明4.2.2、


一文讲清:主流大模型推理部署框架:vLLM、SGLang、TensorRT-LLM、ollama、XInference
智泊AI2026/1/7

本文系统性梳理当前主流的大模型推理部署框架,包括vLLM、SGLang、TensorRT-LLM、Ollama、XInference等。 随着大语言模型技术的迅猛演进,推理部署框架作为贯通模型能力与落地应用的核心枢纽,其战略价值正持续攀升。本文旨在对当前业界广泛采用的 vLLM、SGLang、TensorRT-LLM、Ollama 与 XInference 等主流推理框架展开系统性归纳,围绕核心技术路径、系统架构设计、关键性能指标及典型适用场景等多维度进行深度剖析,为大模型在生产环境中的选型决策


HarmonyOS官方模板集成创新活动-流蓝卡片
万少 VIP.5 如鱼得水2025/12/30

HarmonyOS官方模板集成创新活动-流蓝卡片 ​ 介绍 ​ ​ 流蓝卡片是一款适配了的鸿蒙6-API20的HarmonyOS应用,目的在于给用户提供方便、简单的方式创建好看的卡片,用于将卡片发布到各种社交平台上。 实现过程 ​ ​ 目前是AI Codeing的时代,流蓝卡片其实也是基于AI Coding的产物,人工参与代码部分不超过5%。 ​ 这款应用用到的亮点技术有:GLM4.6 + Gemini-3-pro + 智谱图片生成 + command line 构建鸿蒙工程。 ​ 这套技术组


应对企业微信客户端频繁更新的 RPA 兼容性方案
天空属于哈夫克32025/12/20

一、 引言(Introduction) 核心痛点: 企业微信几乎每月都会进行版本迭代。UI 布局的微调、控件名称的修改、甚至弹窗逻辑的变化,都会导致原本稳定的 RPA 脚本瞬间失效。 研发挑战: 开发者无法阻止客户端更新,但可以通过架构设计,让脚本具备“韧性”,减少因版本更新带来的重复开发工作。 本文目的: 分享如何构建一套版本感知与解耦的 RPA 框架,实现“一次编写,多版本适配”。 二、 兼容性问题的常见类型 UI 属性变更: 某个按钮的 Name 从“发送”变成了“确认发送


AI+虚仿破解实训难题,为无人机火灾救援教学增效赋能
恒点虚拟仿真2025/12/12

在职业教育深化改革的浪潮中,人工智能与虚拟仿真技术的融合正为专业教学带来革命性变化。充分响应政策号召,无人机火灾救援“AI+虚仿”虚实融合创新实训室,为培养高素质应急救援技术技能人才提供全新解决方案。 传统培养模式痛点:实训难实现、教学低效率 传统无人机火灾救援实训长期面临高危场景难复现、设备成本高昂、教学评价主观性强等痛点。尤其在教学管理层面,教师往往需要投入大量时间进行课前准备、课中指导与课后评估,难以实现规模化、精准化人才培养。 智能教学新范式:AI数字教师实现个性化精准指导 实训

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客