You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何用urllib+BeautifulSoup无法获取https://retty.me完整HTML?

问题分析与解决方案

嘿,我来帮你排查下问题!你遇到的情况其实很常见,核心原因大概率是网页内容动态渲染导致的,咱们一步步拆解:

为什么只拿到一个链接?

你用urlopen获取的是服务器返回的初始静态HTML源码,但retty.me这类现代网站很多内容是通过JavaScript动态生成的——也就是说,那些你在浏览器里看到的大量链接,是页面加载完成后,JS脚本才把它们插入到页面中的,初始源码里根本没有这些内容。所以你打印页面只能看到一个链接,BeautifulSoup自然也找不到其他的。

解决办法

1. 用工具模拟浏览器渲染(最直接的方案)

可以用selenium或playwright这类工具,它们能像真实浏览器一样加载页面、执行JS,等页面完全渲染后再获取完整的HTML。这里以selenium为例:

首先安装依赖:

pip install selenium

然后下载对应浏览器的驱动(比如ChromeDriver,要和你的浏览器版本匹配),接着修改代码:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from bs4 import BeautifulSoup
import time

# 替换成你的ChromeDriver路径
service = Service('/path/to/your/chromedriver')
driver = webdriver.Chrome(service=service)

# 打开目标网站
driver.get('https://retty.me')
# 等待3秒让JS完成渲染(也可以用更智能的显式等待,比如等待某个元素加载完成)
time.sleep(3)

# 获取渲染后的完整页面源码
html = driver.page_source
soup = BeautifulSoup(html, 'lxml')

# 提取所有带href的链接
all_links = soup.find_all('a', href=True)
for link in all_links:
    print(link['href'])

# 记得关闭浏览器
driver.quit()

2. 直接请求网站的API接口(更高效的方案)

有些动态网站会通过AJAX请求从后端拉取数据,你可以通过浏览器开发者工具找接口:

  • 打开浏览器F12,切换到「网络」标签
  • 刷新页面,筛选「XHR」或「Fetch」类型的请求
  • 查看每个请求的响应内容,找到包含链接数据的接口
  • 用requests库直接请求这个接口,就能拿到结构化的链接数据,不需要处理HTML

3. 先检查请求头是否被限制

有些网站会识别爬虫请求,返回不完整内容。你可以给请求添加模拟浏览器的User-Agent头试试,用urllib的话代码如下:

from urllib.request import urlopen, Request
from bs4 import BeautifulSoup

# 模拟浏览器的请求头
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'
}
# 构造带请求头的请求
req = Request('https://retty.me', headers=headers)
html = urlopen(req)
soup = BeautifulSoup(html, 'lxml')

# 再次提取链接
links = soup.find_all('a', href=True)
for link in links:
    print(link['href'])

不过这个方法只能解决请求头被拦截的问题,没法解决动态渲染的核心问题,但可以先排除这个可能性。

内容的提问来源于stack exchange,提问作者dip deb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:24:30