使用BeautifulSoup4提取Justdial商家联系信息,遇数字拆分独立class标签问题
JustDial隐藏手机号提取方案
核心逻辑分析
你目前用的 soup.find_all('span', class_ = "class-name")写法只能获取到标签对象,无法直接提取数字的原因是该站点的手机号做了前端反爬处理:
- 单个数字被拆分到独立
<span>标签内,标签无可见文本 - 数字显示完全依赖CSS控制,而非DOM文本内容,分为两种常见实现:类名直接映射数字、CSS精灵图偏移显示数字
排查加密类型
按F12打开开发者工具,选中任意一个数字对应的<span>元素:
- 若右侧样式面板中
class属性为类似call__digit3的格式,直接对应数字内容,属于类名映射加密 - 若样式面板中存在
background-image指向数字小图、同时background-position有不同偏移值,属于CSS精灵图加密
对应实现代码
1. 类名映射加密(最简单)
先手动梳理页面类名与数字的对应关系,替换成你实际页面的类名即可:
# 类名与数字映射表,需根据实际页面调整 digit_map = { "call__digit0": "0", "call__digit1": "1", # 补全0-9的对应关系 } # 号码外层容器class需根据实际页面调整,示例为常见的号码容器class phone_container = soup.find('div', class_='contact-number') if phone_container: digit_spans = phone_container.find_all('span') # 按DOM顺序拼接数字即可得到完整号码 phone_number = "".join([digit_map[span['class'][0]] for span in digit_spans if span.get('class')])
2. CSS精灵图加密
这种需要先梳理偏移量与数字的对应关系:
- 从开发者工具的样式面板中复制数字背景图,下载到本地
- 测量单个数字的宽度,按
background-position的x轴偏移值排序,对应0-9的数字,整理成映射表 - 提取每个
<span>的style属性中的偏移值,拼接得到号码
# 偏移量与数字映射表,需根据实际背景图测量后补全 position_map = { "background-position: 0px 0px": "0", "background-position: -12px 0px": "1", # 补全所有偏移对应的数字 } phone_container = soup.find('div', class_='contact-number') if phone_container: digit_spans = phone_container.find_all('span') phone_number = "".join([position_map[span.get('style').strip()] for span in digit_spans if span.get('style')])
注意事项
- 需给请求添加合规的请求头,至少包含
User-Agent、Referer字段,否则会被反爬拦截返回错误页面 - 动态加载的号码需使用Selenium/Playwright渲染页面后再解析DOM,普通
requests无法获取到渲染后的结构 - 多组号码的页面只需遍历所有号码外层容器,重复上述提取逻辑即可
内容的提问来源于stack exchange,提问作者oldskool
相关产品推荐
相关产品推荐

