如何使用BeautifulSoup从内部网页提取tel链接中的电话号码并整合至DataFrame
如何使用BeautifulSoup从内部网页提取tel链接中的电话号码并整合至DataFrame
看起来你已经有了非常清晰的思路方向,我来帮你完善这个流程,把客户ID对应的电话号码抓取下来并整合到目标DataFrame里~
先明确你的核心需求:从包含客户ID的初始数据集出发,遍历每个ID请求对应详情页,提取页面中tel:链接里的手机号,最终生成ID与手机号绑定的DataFrame。
你的初始数据集
| Date | ID | Comment |
|---|---|---|
| 20240514 May, 14 22:00 | R_111 | Le client ne répond pas |
目标数据集
| ID | Phone |
|---|---|
| R_111 | 77777777777 |
现有代码的小调整与完整流程实现
你写的get_client_phone函数逻辑基本没问题,但有个关键细节需要修正:你的客户ID是R_111,但请求URL需要的是纯数字111,所以得先把ID里的R_前缀去掉;另外还需要补充整合DataFrame的部分。
以下是完善后的完整代码:
import requests from bs4 import BeautifulSoup import pandas as pd import time # 用于添加请求延迟,避免被反爬 # 配置请求头(模拟浏览器请求,避免被网站拦截) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' } # 这里替换成你实际的payload配置(如果需要的话) cfg = type('Config', (object,), {'payload': {}})() def get_client_phone(client_id): # 从R_xxx格式的ID中提取纯数字部分,适配URL的id参数 try: numeric_id = client_id.split('_')[-1] except IndexError: print(f"客户ID格式错误: {client_id}") return None _url = f"https://example.com/client/?id={numeric_id}" try: # 发送请求,添加延迟避免频繁请求 time.sleep(1) response = requests.get(_url, data=cfg.payload, headers=headers) response.raise_for_status() # 主动抛出HTTP错误(比如404、500) except requests.exceptions.RequestException as e: print(f"请求客户{client_id}的页面失败: {str(e)}") return None # 解析页面 soup = BeautifulSoup(response.text, 'html.parser') # 定位phone区块并提取tel链接 phone_element = soup.find(id='phone') if not phone_element: print(f"未找到客户{client_id}的电话区块") return None phone_link = phone_element.find('a', href=True) if phone_link and 'tel:' in phone_link['href']: # 去除tel:前缀,得到纯手机号 phone_number = phone_link['href'].replace('tel:', '') return phone_number else: print(f"未找到客户{client_id}的有效电话链接") return None # ---------------------- 处理DataFrame部分 ---------------------- # 这里替换成你实际的初始数据集(比如从CSV/Excel读取:pd.read_csv('your_data.csv')) initial_df = pd.DataFrame({ 'Date': ['20240514 May, 14 22:00'], 'ID': ['R_111'], 'Comment': ['Le client ne répond pas'] }) # 遍历初始DataFrame,收集ID与对应的手机号 result_data = [] for _, row in initial_df.iterrows(): client_id = row['ID'] phone_num = get_client_phone(client_id) result_data.append({ 'ID': client_id, 'Phone': phone_num }) # 生成最终的目标DataFrame result_df = pd.DataFrame(result_data) # 可以把结果保存到文件 # result_df.to_csv('client_phones.csv', index=False) print("最终结果:") print(result_df)
额外优化建议
- 反爬防护:如果数据量较大,除了添加
time.sleep(1),还可以使用随机延迟time.sleep(random.uniform(0.5, 2)),或者使用代理IP池; - 批量处理效率:如果客户数量很多,可以使用
concurrent.futures.ThreadPoolExecutor实现多线程请求,提升抓取速度; - 错误记录:可以把抓取失败的ID单独保存到一个列表或文件,方便后续手动排查;
- 页面动态加载:如果你的目标页面的
contactBlock是点击Contact按钮后才加载的(比如通过JS动态渲染),那requests就无法获取到内容,这时候需要改用selenium来模拟浏览器点击操作。
备注:内容来源于stack exchange,提问作者mikhailtugushev
相关产品推荐
相关产品推荐

