如何爬取IBM X-Force Exchange获取IP风险评分及归属机构?代码遇阻求解
IBM X-Force Exchange 爬虫返回None的问题解决办法
问题描述
工作中需定期生成含10个IP的报告,手动在IBM X-Force Exchange查询每个IP的风险评分及WHOIS信息(主要为所属机构)。尝试用BeautifulSoup编写爬虫函数实现自动化,但函数始终返回None,发现BeautifulSoup无法获取页面完整HTML,疑惑此类网站是否可通过爬虫完成需求。
用户提供的爬虫代码:
from bs4 import BeautifulSoup def fetch_risk_level(ip_address): """Fetches the risk level of an IP address from X-Force Exchange. Args: ip_address (str): The IP address to fetch the risk level for. Returns: str: The risk level of the IP address, or None if not found. """ url = f"https://exchange.xforce.ibmcloud.com/ip/{ip_address}" response = requests.get(url) soup = BeautifulSoup(response.content, "html.parser") risk_level_element = soup.find("div", class_="risklevelbar") if risk_level_element is not None: risk_score = risk_level_element.find("div", class_="scorebackgroundfilter numtitle").text return risk_score else: return None
问题原因
- 动态内容渲染:IBM X-Force Exchange的页面内容是通过JavaScript动态加载的,
requests.get()只能获取初始静态HTML,无法获取JS渲染后的完整DOM结构,导致BeautifulSoup找不到目标元素。 - 反爬拦截:网站可能会检测非浏览器发起的请求,返回不完整内容或直接拦截,导致无法获取所需数据。
可行解决方案
1. 使用官方API(推荐)
IBM X-Force Exchange提供官方API,这是最稳定合规的方式。需先注册账号获取API密钥,直接通过API查询IP的风险评分和WHOIS信息:
import requests # 替换为你的API密钥和密码 API_KEY = "your_api_key" API_PASSWORD = "your_api_password" def fetch_ip_info(ip_address): url = f"https://api.xforce.ibmcloud.com/ipr/{ip_address}" auth = (API_KEY, API_PASSWORD) response = requests.get(url, auth=auth) if response.status_code == 200: data = response.json() risk_score = data.get("score") org_info = data.get("whois", {}).get("org") return {"risk_score": risk_score, "organization": org_info} return None
- 优势:官方支持,数据准确,不会触发反爬,还能获取结构化的完整数据。
2. 用无头浏览器处理动态内容
如果必须使用爬虫,改用Selenium或Playwright这类模拟浏览器的工具,等待JS加载完成后再获取完整HTML:
from bs4 import BeautifulSoup 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 def fetch_risk_level(ip_address): url = f"https://exchange.xforce.ibmcloud.com/ip/{ip_address}" driver = webdriver.Chrome() # 需提前安装ChromeDriver driver.get(url) try: # 等待目标元素加载完成 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "scorebackgroundfilter")) ) html = driver.page_source soup = BeautifulSoup(html, "html.parser") return soup.find("div", class_="scorebackgroundfilter numtitle").text finally: driver.quit()
- 注意:需添加请求间隔,避免批量快速爬取触发反爬机制。
总结
优先选择官方API,既合规又高效;若必须用爬虫,使用无头浏览器处理动态内容,但要严格遵守网站的使用规则,避免被封禁。
内容的提问来源于stack exchange,提问作者Malhar Shembekar
相关产品推荐
相关产品推荐

