如何解决爬取巴西央行纪要页面时外部URL加载文本为空的问题
问题根因
你收集到的会议纪要页面属于*客户端渲染(CSR)*页面,普通requests请求只能拿到无业务内容的初始HTML骨架,核心文本是页面加载完成后由JS异步请求额外接口填充的,因此直接解析返回的HTML会得到空结果。
最优解决方法:直接调用内容接口
巴西央行官网所有公开内容都有对应的结构化数据接口,不需要解析前端渲染页面,你可以直接在原有逻辑基础上请求内容接口获取文本,效率远高于页面渲染方案。
完整示例代码如下:
import requests # 原有获取列表的逻辑 list_url = "https://www.bcb.gov.br/api/servico/sitebcb/atascopom-conteudo/ultimas?quantidade=1000&filtro=" list_data = requests.get(list_url).json() meeting_contents = [] for item in list_data['conteudo']: # 直接拼接内容接口地址,不需要请求前端页面链接 content_api = f"https://www.bcb.gov.br/api/servico/sitebcb/atascopom-conteudo/principal?url=https://www.bcb.gov.br/{item['LinkPagina']}" content_resp = requests.get(content_api) content_resp.encoding = 'utf-8' content_data = content_resp.json() # 提取核心正文内容,可根据需要调整提取字段 if 'conteudo' in content_data: meeting_text = content_data['conteudo'].get('OutrasInformacoes', '') meeting_contents.append({ "title": item.get('Titulo', ''), "publish_time": item.get('DataPublicacao', ''), "content": meeting_text, "page_url": f"https://www.bcb.gov.br/{item['LinkPagina']}" }) # 打印第一条测试 print(meeting_contents[0])
备选方案:使用无头浏览器渲染页面
如果后续接口规则变更无法直接调用,可以使用无头浏览器模拟浏览器加载行为,等页面渲染完成后再提取内容,示例使用selenium实现:
import requests from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 配置无头模式 chrome_options = Options() chrome_options.add_argument("--headless=new") chrome_options.add_argument("--disable-gpu") driver = webdriver.Chrome(options=chrome_options) # 原有获取链接逻辑 list_url = "https://www.bcb.gov.br/api/servico/sitebcb/atascopom-conteudo/ultimas?quantidade=1000&filtro=" list_data = requests.get(list_url).json() links = [f"https://www.bcb.gov.br/{item['LinkPagina']}" for item in list_data['conteudo'][:178]] meeting_contents = [] for link in links: driver.get(link) # 等待正文元素加载完成 content_ele = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "conteudo")) ) meeting_contents.append({ "page_url": link, "content": content_ele.text }) driver.quit()
内容的提问来源于stack exchange,提问作者TiagoS
相关产品推荐
相关产品推荐

