如何爬取网页中所有新闻文章链接?现有代码仅爬取部分链接
一次性爬取目标网站所有新闻文章链接的解决方案
我来帮你搞定这个爬取难题!你之前遇到的问题核心是没抓住新闻链接的统一特征,同时没排除非新闻区域的干扰。下面是具体的解决思路和可直接运行的代码:
问题分析
目标网站的新闻文章链接通常带有统一的URL标识(比如包含/News/Article/路径),而非新闻链接(下拉菜单、导航栏)的路径完全不同。另外,下拉菜单这类非新闻内容所在的HTML容器也有特定标识,可以先移除这些区域避免误爬。
完整实现代码
import requests from bs4 import BeautifulSoup def get_all_news_links(): # 目标页面URL target_url = "http://www3.asiainsurancereview.com/News" # 模拟浏览器请求头,避免被反爬拦截 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" } # 获取页面内容 response = requests.get(target_url, headers=headers) response.raise_for_status() # 检查请求是否成功 soup = BeautifulSoup(response.text, "html.parser") # 第一步:移除所有非新闻区域(比如下拉菜单、导航栏) # 根据页面实际HTML结构调整要移除的容器类名 for non_news_container in soup.find_all(class_=["dropdown", "nav-main"]): non_news_container.decompose() # 第二步:筛选所有符合新闻链接特征的URL base_url = "http://www3.asiainsurancereview.com" news_links = set() # 用集合自动去重 for a_tag in soup.find_all("a", href=True): href = a_tag["href"] # 通过专属路径判断是否为新闻文章链接 if "/News/Article/" in href: # 处理相对路径,转为完整绝对URL if not href.startswith("http"): full_link = base_url + href else: full_link = href news_links.add(full_link) return news_links # 执行并输出结果 if __name__ == "__main__": all_news = get_all_news_links() print(f"共找到 {len(all_news)} 条新闻链接:") for idx, link in enumerate(all_news, 1): print(f"{idx}. {link}")
关键说明
- 移除非新闻区域:通过
decompose()方法删除下拉菜单、导航栏这类容器,从根源上排除非新闻链接的干扰。你可以根据页面实际的HTML结构调整要移除的容器类名。 - 精准筛选新闻链接:利用新闻URL的统一特征
/News/Article/来匹配,这比单纯匹配http开头的链接更准确,能直接过滤掉所有非新闻链接。 - 自动去重:用集合存储链接,自动过滤页面中重复出现的推荐链接或重复加载的内容。
- 反爬适配:添加
User-Agent请求头,模拟正常浏览器访问,避免被网站直接拦截。
额外注意事项
如果页面存在动态加载的新闻(比如滚动到底部才加载更多内容),静态爬取方法就不够了,这时需要用selenium模拟浏览器滚动加载,再提取链接。不过从当前页面的结构来看,静态爬取应该能覆盖大部分新闻链接。
内容的提问来源于stack exchange,提问作者Kristada673




