import requests
from bs4 import BeautifulSoup
import pandas as pd
import jieba
import jieba.posseg as pseg
import time
import random
import json
import re
from urllib.parse import quote, unquote
# 配置jieba分词器
jieba.initialize()
# 添加金融科技领域专有名词和公司名称
tech_keywords = ['科技', '技术', '数字', '智能', '数据', '信息', '云', 'AI', '区块链', '金融科技']
jieba.add_word('北京银行', freq=1000, tag='nt')
jieba.add_word('北银', freq=1000, tag='nt')
jieba.add_word('BNK', freq=1000, tag='nt')
# !!!【核心修改部分】!!! 直接使用关键词构建URL模板
base_url_template = "https://www.ringdata.com/news/result?keywords={keywords}&page={page}"
# 对关键词进行URL编码
encoded_keywords = quote("北京银行 科技公司 合作")
# 请求头配置(替换为你的实际Cookie)
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36",
"Cookie": "x-hng=lang=zh-CN&domain=www.ringdata.com; tokenWeb=eyJhbGci...", # !!!务必替换为你的有效Cookie!!!
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1"
}
def fetch_all_news_pages():
"""获取所有页面的新闻数据"""
all_news = []
page = 1
max_pages = 50 # 安全限制,防止无限循环
print("开始爬取北京银行合作新闻...")
while page <= max_pages:
print(f"正在处理第 {page} 页。")
# !!!【核心修改部分】!!! 直接拼接URL
current_url = base_url_template.format(keywords=encoded_keywords, page=page)
try:
# 发送请求
response = requests.get(
current_url, # 使用新拼接的URL
headers=headers,
timeout=30
)
response.raise_for_status()
# 打印状态和URL用于调试(完成后可注释掉)
# print(f"状态码: {response.status_code}, 请求URL: {current_url}")
# 解析HTML
soup = BeautifulSoup(response.text, 'html.parser')
# 检查是否有结果 - 根据您提供的截图修改选择器
no_results = soup.select_one('.no-result')
if no_results and "没有找到相关内容" in no_results.text:
print(f"第 {page} 页无结果,停止爬取")
break
# !!!【关键修改】!!! 获取新闻条目 - 选择器可能需要调整
# 根据您提供的截图,新闻列表项可能是 .info-item
news_items = soup.select('.info-item')
# 如果上面选择器不行,可以尝试更宽泛的选择器,例如:
# news_items = soup.select('.info-list li')
# news_items = soup.select('.list-content > div')
if not news_items:
# 打印一段HTML内容来调试,帮助确定正确的选择器
print(f"第 {page} 页未找到 .info-item 元素,正在尝试确定页面结构...")
# 查看页面内容的前500字符,寻找线索
# print(response.text[:500])
# 或者查找包含“北京银行”的标签
potential_items = soup.find_all(string=re.compile("北京银行"))
if potential_items:
print(f" 但在页面中找到了 {len(potential_items)} 处包含'北京银行'的文本。")
print(f"第 {page} 页无数据,停止爬取")
break
print(f"发现 {len(news_items)} 条新闻")
# 处理每条新闻
for item in news_items:
news_data = process_news_item(item)
if news_data:
all_news.append(news_data)
# 检查是否还有下一页(可选,更智能的停止条件)
next_page = soup.select_one('.pagination .next:not(.disabled)') # 根据实际分页控件调整选择器
if not next_page:
print("已是最后一页,停止爬取")
break
# 随机延时防止被封
sleep_time = random.uniform(2, 5) # 适当延长间隔时间
time.sleep(sleep_time)
page += 1
except requests.exceptions.RequestException as e:
print(f"请求第 {page} 页失败: {str(e)}")
break
except Exception as e:
print(f"处理第 {page} 页时发生未知错误: {str(e)}")
break
return all_news
# ... process_news_item, extract_tech_companies 等其他函数保持不变 ...
def process_news_item(item):
"""处理单条新闻并提取合作信息"""
try:
# !!!【可能需要修改】!!! 根据实际HTML结构调整选择器
# 提取标题和链接
title_elem = item.select_one('a') # 尝试选择第一个a标签,或者更精确的选择器如 '.title a'
if not title_elem:
# 尝试其他可能的选择器
title_elem = item.select_one('.news-title, .title, .item-title')
if not title_elem:
print(" 无法找到标题元素,跳过此条")
return None
title = title_elem.get_text(strip=True)
relative_url = title_elem.get('href', '')
# 确保URL是完整的
if relative_url and not relative_url.startswith('http'):
if relative_url.startswith('/'):
full_url = f"https://www.ringdata.com{relative_url}"
else:
full_url = f"https://www.ringdata.com/{relative_url}"
else:
full_url = relative_url
# 提取来源和日期 - 选择器需要根据实际页面调整
source_elem = item.select_one('.source, .news-source, .info-source')
source = source_elem.get_text(strip=True) if source_elem else "未知来源"
date_elem = item.select_one('.date, .news-date, .time')
date = date_elem.get_text(strip=True) if date_elem else "未知日期"
# 简单打印一下抓取到的信息
print(f" 抓取到: {title[:50]}... | 来源: {source} | 日期: {date}")
# 获取新闻内容
content = fetch_news_content(full_url) if full_url else ""
full_text = f"{title}。{content}"
# 分析内容提取实体
tech_companies = extract_tech_companies(full_text)
coop_companies = extract_cooperation_companies(full_text, tech_companies)
# 提取合作时间
coop_date = extract_cooperation_date(content, date)
# 只保留包含合作的新闻
if not coop_companies:
print(f" 未在『{title[:30]}...』中识别出合作关系,跳过。")
return None
print(f" 分析成功: 与 {list(coop_companies)} 合作")
return {
"银行": "北京银行",
"合作公司": list(coop_companies),
"合作时间": coop_date,
"新闻标题": title,
"新闻发布时间": date,
"新闻来源": source,
"新闻链接": full_url
}
except Exception as e:
print(f"处理新闻时出错: {str(e)}")
return None
# ... 其余函数 save_results, main 等保持不变 ...为什么运行不了,
最新发布