从带加载更多的JS动态网页获取全部链接失败求助
动态加载网页爬取链接不全的问题排查与修复
问题背景
爬取科威特外交部英文新闻页(https://www.mofa.gov.kw/en/media-center/news/)时,尝试通过设置page参数模拟翻页加载,但最终仅获取到103条唯一链接,无法抓取全部内容。原脚本如下:
import requests from bs4 import BeautifulSoup BASE_URL = "https://www.mofa.gov.kw" PAGE_URL = "https://www.mofa.gov.kw/en/media-center/news/" headers = {'User-Agent': 'Mozilla/5.0'} unique_urls = set() with open("urls.txt", "w", encoding="utf-8") as f: for page in range(1, 2500): # can adjust this page_params = {"page": page, "from": "None", "to": "None"} response = requests.get(PAGE_URL, params=page_params, headers=headers) if response.status_code != 200: print(f"Failed to access page {page}") continue soup = BeautifulSoup(response.text, "html.parser") for link in soup.select("a[href^='/en/media-center/news/']"): full_url = BASE_URL + link.get('href') unique_urls.add(full_url) for url in unique_urls: f.write(url + "\n")
问题排查
- 参数不匹配网站实际逻辑:原脚本中
from和to参数设为None,但该网站的加载更多功能可能需要有效的参数格式,或者分页机制并非直接通过递增page参数实现。当page超过网站实际存在的页数后,服务器会返回重复内容或空列表,无法获取新链接。 - 无终止条件:循环硬编码到2500页,但实际到某一页后就没有新内容了,后续循环只是重复抓取已有的链接,导致总数停在103。
- 链接选择器冗余:当前选择器会抓取页面上所有以
/en/media-center/news/开头的链接,包括分页导航栏的链接,虽然用集合去重,但会浪费请求资源。
修复方案
1. 先分析网站实际请求逻辑
打开浏览器开发者工具(F12),切换到Network标签,点击页面的“加载更多”按钮,观察发送的请求:
- 确认请求方法(GET/POST)、正确的参数名称和格式,比如是否需要
offset而非page,或者from/to需要是具体的日期字符串。 - 检查当没有更多内容时,服务器的返回特征(比如返回空的新闻列表、特定提示文本)。
2. 修复后的脚本示例
假设通过分析发现,网站实际使用page参数分页,但from/to参数需要留空而非设为None,且当某一页没有新链接时停止循环:
import requests from bs4 import BeautifulSoup BASE_URL = "https://www.mofa.gov.kw" PAGE_URL = "https://www.mofa.gov.kw/en/media-center/news/" headers = {'User-Agent': 'Mozilla/5.0'} unique_urls = set() page = 1 no_new_links_count = 0 with open("urls.txt", "w", encoding="utf-8") as f: while no_new_links_count < 3: # 连续3页无新链接则停止 # 修正参数:from和to设为空字符串,而非None page_params = {"page": page, "from": "", "to": ""} response = requests.get(PAGE_URL, params=page_params, headers=headers) if response.status_code != 200: print(f"页面 {page} 请求失败,状态码:{response.status_code}") page += 1 continue soup = BeautifulSoup(response.text, "html.parser") # 更精准的选择器:只抓取新闻条目内的链接,排除分页导航 news_links = soup.select("div.news-item a[href^='/en/media-center/news/']") current_page_urls = set() for link in news_links: full_url = BASE_URL + link.get('href') current_page_urls.add(full_url) # 检查当前页是否有新链接 if not current_page_urls.difference(unique_urls): no_new_links_count += 1 else: no_new_links_count = 0 unique_urls.update(current_page_urls) print(f"已抓取第 {page} 页,累计获取 {len(unique_urls)} 条唯一链接") page += 1 # 写入文件 for url in unique_urls: f.write(url + "\n") print(f"抓取完成,共获取 {len(unique_urls)} 条唯一链接,已保存到 urls.txt")
关键改进点
- 修正请求参数:将
from和to设为空字符串,匹配网站实际接受的参数格式。 - 添加终止逻辑:连续3页没有新链接时停止循环,避免无效请求。
- 精准选择器:仅抓取新闻条目内的链接,排除分页导航的冗余链接,提升效率。
- 状态反馈:打印每一页的抓取情况,方便调试。
补充说明
如果上述调整后仍无法获取更多链接,可能是网站采用了JavaScript渲染或反爬机制:
- 尝试使用
selenium或playwright模拟浏览器加载页面,触发“加载更多”按钮。 - 检查是否需要携带其他请求头(如
Referer、Cookie)才能正常获取内容。
内容的提问来源于stack exchange,提问作者kutsalzamazingo
相关产品推荐
相关产品推荐

