
本文详解为何 requests + beautifulsoup 无法获取 dtcc 搜索页的真实结果链接,并提供基于 selenium 的可靠解决方案,支持无头模式自动化抓取动态加载的搜索结果 url。
DTCC 官网(https://www.php.cn/link/8dc56b3dd5380fcd7402ce0fbc75cb1e)的搜索结果是通过 JavaScript 动态渲染生成的——页面初始 HTML 中不包含实际的搜索结果链接,而是由前端脚本(如 React 或 AJAX)在浏览器中运行后才插入 DOM。因此,使用 requests 获取的原始 HTML 仅含占位结构(如空的
你原代码中的正则匹配 href 含 "http" 的 标签,实际捕获的是页面头部、导航栏、脚本资源等静态链接,而非动态注入的搜索结果项,这是典型“服务端渲染缺失”导致的爬虫失效场景。
✅ 正确做法是:使用浏览器自动化工具执行 JavaScript,等待内容加载完成后再提取。推荐方案如下:
方案一:纯 Selenium 提取(推荐)
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time
search_url = "https://www.php.cn/link/8dc56b3dd5380fcd7402ce0fbc75cb1e?q=aggregated%20transaction%20data"
# 配置无头 Chrome(不显示界面,适合服务器部署)
opts = Options()
opts.add_argument('--headless')
opts.add_argument('--no-sandbox')
opts.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(options=opts)
try:
driver.get(search_url)
# 等待搜索结果容器加载并至少出现一个链接(更健壮可改用 WebDriverWait)
time.sleep(5)
results_container = driver.find_element(By.CLASS_NAME, 'search-results')
result_links = results_container.find_elements(By.TAG_NAME, 'a')
for link in result_links:
href = link.get_attribute('href')
if href and not href.startswith('#') and 'javascript:' not in href:
print(href)
finally:
driver.quit() # 确保关闭浏览器进程方案二:Selenium + BeautifulSoup 混合(灵活性更高)
若需复用 BeautifulSoup 的解析能力(如提取标题、摘要等),可在 JS 渲染后获取完整 HTML:
立即学习“Java免费学习笔记(深入)”;
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
for a in soup.select('.search-results a[href]'):
print(a['href'])⚠️ 注意事项:
- 必须设置合理等待时间(或使用 WebDriverWait 显式等待 .search-results a 出现),避免因加载延迟导致空结果;
- 生产环境建议添加异常处理(如 NoSuchElementException)、超时控制及 User-Agent 设置;
- 确保 ChromeDriver 版本与本地 Chrome 浏览器兼容;
- 遵守 robots.txt(DTCC 的 /robots.txt 允许 /search,但仍建议控制请求频率,避免对服务器造成压力)。
总结:当目标内容由 JavaScript 动态注入时,requests 是无效的“静态快照工具”,而 Selenium 是模拟真实用户行为的“动态执行引擎”。掌握这一区分,是突破现代 SPA(单页应用)网站反爬限制的关键一步。










