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

如何用BeautifulSoup4提取<script>标签中的内容?

问题描述

编写网站解析器时,使用BeautifulSoup4无法获取<script>标签内的俄语文本,输出为空字符串。需要提取91个这类脚本块中的任务文本并存入数据库。

示例HTML结构:

<tr>
  <td class="egeno"><span>1</span></td>
  <td class="topicview">
  <script>
  document.write( '(№&nbsp;4840) ' ); 
  document.write( changeImageFilePath('На рисунке схема дорог Н-ского района изображена в виде графа, в таблице содержатся сведения о длине этих дорог в километрах. <br/><img src="4840.gif">Так как таблицу и схему рисовали независимо друг от друга, нумерация населённых пунктов в таблице никак не связана с буквенными обозначениями на графе. Известно, что длина дороги ЗЕ равна 15 км. Определите длину дороги БГ. В ответе запишите целое число – длину дороги в километрах.') );
  </script>
  </td>
</tr>
<tr>
  <td class="egeno"><span>1</span></td>
  <td class="topicview">
  <script>
  document.write( '(№&nbsp;4839) ' ); 
  document.write( changeImageFilePath('На рисунке схема дорог Н-ского района изображена в виде графа, в таблице содержатся сведения о длине этих дорог в километрах. <br/><img src="4839.gif">Так как таблицу и схему рисовали независимо друг от друга, нумерация населённых пунктов в таблице никак не связана с буквенными обозначениями на графе. Известно, что длина дороги ЗЕ равна 15 км. Определите длину дороги БГ. В ответе запишите целое число – длину дороги в километрах.') );
  </script>
  </td>
</tr>

现有代码:

import requests
from bs4 import BeautifulSoup
import os, sqlite3
import re
import json
i = 1


task1_hrefs = soup.find_all(class_='topicview')
print(task1_hrefs)

for task in task1_hrefs:
    task_text = task.text
    print(i, "", f"{task_text}")
解决方案

问题出在.text属性会返回标签渲染后的文本内容,而<script>标签的内容是JavaScript代码,不会被BeautifulSoup渲染,所以需要直接提取脚本的原始内容,再用正则匹配目标文本。

修改后的代码

import requests
from bs4 import BeautifulSoup
import re
import sqlite3

# 假设已完成页面请求与解析
# response = requests.get('目标URL')
# soup = BeautifulSoup(response.text, 'html.parser')

task_containers = soup.find_all(class_='topicview')

# 初始化数据库连接
conn = sqlite3.connect('tasks.db')
cursor = conn.cursor()
# 创建任务表(不存在则创建)
cursor.execute('''CREATE TABLE IF NOT EXISTS tasks
                  (id INTEGER PRIMARY KEY AUTOINCREMENT, task_content TEXT)''')

for idx, container in enumerate(task_containers, 1):
    # 定位当前容器内的<script>标签
    script_tag = container.find('script')
    if not script_tag or not script_tag.string:
        continue
    
    # 获取脚本的原始文本内容
    script_content = script_tag.string.strip()
    
    # 提取任务编号
    number_pattern = re.compile(r'document\.write\(\s*\'\(№&nbsp;(\d+)\)\s*\'\s*\);')
    number_match = number_pattern.search(script_content)
    
    # 提取俄文任务文本(匹配changeImageFilePath括号内的内容,支持多行)
    text_pattern = re.compile(r'changeImageFilePath\(\s*\'(.*?)\'\s*\);', re.DOTALL)
    text_match = text_pattern.search(script_content)
    
    if number_match and text_match:
        task_number = number_match.group(1)
        raw_text = text_match.group(1)
        # 清理HTML标签与实体,优化文本格式
        cleaned_text = raw_text.replace('<br/>', '\n').replace('&quot;', '"')
        full_task = f"(№ {task_number}) {cleaned_text}"
        
        print(idx, full_task)
        
        # 将任务文本存入数据库
        cursor.execute('INSERT INTO tasks (task_content) VALUES (?)', (full_task,))

# 提交数据库操作并关闭连接
conn.commit()
conn.close()

关键说明

  1. 提取脚本内容:使用script_tag.string获取<script>标签内的原始代码(若脚本包含多个文本节点,可改用''.join(script_tag.strings))。
  2. 正则匹配:
    • 用正则提取document.write中的任务编号
    • 启用re.DOTALL参数,让正则表达式的.匹配换行符,适配多行的任务文本
  3. 文本清理:替换HTML标签(如<br/>)和实体(如&quot;),让文本更易读
  4. 数据库存储:通过SQLite3将处理后的文本批量存入数据库,确保数据持久化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:59:17