如何用R从需密码验证的SABI数据库自动爬取CNAE与企业规模信息?
从SABI提取企业信息并整合到DataFrame的实现方案
合法合规提醒
SABI数据库受版权保护,所有数据提取操作必须严格遵守其用户协议,禁止未经授权的批量爬取行为。
两种可行实现方法
1. 优先使用官方API(最稳定合规)
如果你的SABI账号有API访问权限(学术/企业授权用户通常可申请),这是最优解:
- 联系SABI管理员获取API密钥及接口文档
- 用
requests库发送带身份验证的请求,传入企业的唯一标识(如西班牙税号NIF) - 解析返回的结构化数据,提取CNAE代码和企业规模字段
- 将提取结果匹配到现有DataFrame,新增对应列
示例代码(假设API支持NIF查询):
import pandas as pd import requests import os # 读取现有企业数据 df = pd.read_csv('spanish_companies.csv') # 从环境变量读取账号信息(避免硬编码) SABI_USER = os.getenv('SABI_USER') SABI_PASS = os.getenv('SABI_PASS') API_ENDPOINT = "https://api.sabi.com/company-details" def fetch_sabi_data(nif): params = {"nif": nif} # 发送带基础认证的请求 resp = requests.get(API_ENDPOINT, auth=(SABI_USER, SABI_PASS), params=params) if resp.status_code == 200: data = resp.json() return pd.Series([data['cnae']['code'], data['size']['category']]) return pd.Series([None, None]) # 批量提取并合并 df[['CNAE代码', '企业规模']] = df['nif'].apply(fetch_sabi_data) # 保存结果 df.to_csv('companies_with_sabi_info.csv', index=False)
2. Selenium浏览器自动化(无API时备选)
如果没有API权限,可模拟人工操作浏览器提取数据,但需注意账号风险:
- 确保你的账号允许自动化操作,避免触发反爬机制被封禁
- 使用
selenium控制浏览器完成登录、搜索、数据提取流程
示例代码:
import pandas as pd from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from webdriver_manager.chrome import ChromeDriverManager import time import random # 初始化Chrome浏览器 driver = webdriver.Chrome(ChromeDriverManager().install()) driver.get("https://sabi.com/login") # 完成登录 driver.find_element(By.ID, "username").send_keys("你的账号") driver.find_element(By.ID, "password").send_keys("你的密码") driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click() def extract_sabi_info(company_name): # 搜索企业 search_box = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "company-search")) ) search_box.clear() search_box.send_keys(company_name) driver.find_element(By.CSS_SELECTOR, "#search-btn").click() # 添加随机等待,规避反爬 time.sleep(random.uniform(2, 4)) # 提取目标数据 try: cnae = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "cnae-code")) ).text company_size = driver.find_element(By.CLASS_NAME, "company-size-label").text return pd.Series([cnae, company_size]) except Exception: return pd.Series([None, None]) # 处理现有DataFrame df = pd.read_csv('spanish_companies.csv') df[['CNAE代码', '企业规模']] = df['company_name'].apply(extract_sabi_info) # 清理资源并保存 driver.quit() df.to_csv('companies_with_sabi_info.csv', index=False)
核心注意事项
- 账号安全: 不要在代码中硬编码账号密码,用环境变量或加密配置文件存储
- 反爬规避: 自动化时添加随机等待时间,避免高频请求触发验证码或封禁
- 数据匹配: 优先用唯一标识(如NIF)搜索,比企业名称更准确,减少匹配错误
- 错误处理: 必须加入异常捕获,处理搜索无结果、页面加载失败等情况,避免脚本中断
内容的提问来源于stack exchange,提问作者EI_Stats
相关产品推荐
相关产品推荐

