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

如何用Python+bs4读取完整网页?requests仅返回页面前半部分

问题根因

拿不到完整<body>内容的核心原因有两个:

  • 站点存在基础反爬校验:原生requests默认携带的User-Agent等请求头会标识自身为爬虫程序,站点识别后仅返回不完整的<head>片段,拒绝下发正文资源
  • 词条内容为JS动态渲染:页面初始返回的HTML骨架中不包含<terms>节点下的术语、释义内容,需要前端执行JS逻辑、拉取接口数据后才会把目标内容插入DOM。直接保存静态HTML不会触发JS执行,这也是浏览器“另存为HTML”拿不到完整内容的原因。
解决方案

按实现成本从低到高选择:

方案1:补全浏览器请求头,直连尝试获取

先模拟真实浏览器的请求头,绕过最基础的UA校验,部分场景下可以直接拿到完整内容:

import requests
from bs4 import BeautifulSoup

target_url = "https://dictionary.apa.org/caffeine-intoxication"
# *提示:请求头可以从自己浏览器的F12网络面板中复制同域名请求的头信息,避免被识别为爬虫*
request_headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
    "Referer": "https://dictionary.apa.org/"
}

response = requests.get(target_url, headers=request_headers, timeout=15)
response.encoding = "utf-8"
# 检查返回内容是否包含目标<terms>标签
if "<terms>" in response.text:
    soup = BeautifulSoup(response.text, "html.parser")
    for term_node in soup.select("terms term"):
        term = term_node.select_one("hw").get_text(strip=True)
        definition = term_node.select_one("dd").get_text(strip=True, separator=" ")
        print(f"术语:{term}\n释义:{definition}\n---")
else:
    print("直连未拿到正文,换无头浏览器方案")

方案2:使用无头浏览器模拟真实访问,等待JS渲染完成后提取内容

如果方案1失效,说明站点有更严格的反爬(比如TLS指纹校验、JS验证、内容完全异步加载),直接用浏览器内核渲染页面,等所有资源加载、JS执行完成后再提取DOM,能拿到和手动打开浏览器完全一致的内容:

  1. 先安装依赖:
pip install playwright
playwright install chromium
  1. 爬取代码:
import time
import random
from playwright.sync_api import sync_playwright
from bs4 import BeautifulSoup

def crawl_apa_dictionary(url):
    with sync_playwright() as p:
        # headless=False可以弹出浏览器窗口,遇到人机验证时可以手动操作
        browser = p.chromium.launch(headless=True)
        page = browser.new_page(
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
        )
        page.goto(url, wait_until="networkidle")
        # 等待术语节点加载完成,最长等10秒
        page.wait_for_selector("terms term", timeout=10000)
        full_html = page.content()
        browser.close()
    
    soup = BeautifulSoup(full_html, "html.parser")
    result = []
    for term_node in soup.select("terms term"):
        term = term_node.select_one("hw").get_text(strip=True)
        definition = term_node.select_one("dd").get_text(strip=True, separator=" ")
        result.append((term, definition))
    return result

if __name__ == "__main__":
    test_url = "https://dictionary.apa.org/caffeine-intoxication"
    term_list = crawl_apa_dictionary(test_url)
    for word, desc in term_list:
        print(f"术语:{word}\n释义:{desc}\n---")
爬取注意事项
  • 控制请求频率,每次请求间隔加2-5秒的随机延时,避免IP被封禁
  • 爬取内容仅可用于个人学习,不要批量传播受版权保护的词典内容
  • 如果遇到人机验证,将headless=True改为headless=False手动通过验证后即可正常爬取

内容的提问来源于stack exchange,提问作者Andrey Glinsky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 20:06:26