求助:Python提取网页Script变量数据、下载PDF并生成DataFrame
问题分析与修复:提取供应链地图数据失败
我来帮你排查代码里的问题,以及给出能正常工作的解决方案:
你的代码存在的核心问题
- 正则表达式太简陋:你写的
r"var locations = ."里的.只能匹配单个字符,完全抓不到locations这个大数组的完整内容。目标变量是一个包含所有设施数据的JS数组,得用能匹配多行、直到数组结束的正则规则。 - Script标签处理错误:
soup.find_all("script")返回的是页面所有script标签的列表,你直接用p.match(data)是在尝试匹配整个列表对象,这显然不对——得遍历每个script标签的文本内容,逐个去匹配正则。
修正后的完整代码
下面是能成功提取数据、下载PDF并生成Excel表格的代码:
import requests from bs4 import BeautifulSoup import re import pandas as pd import os import urllib.request from urllib.parse import urljoin # 目标页面URL url = 'https://goldenagri.com.sg/sustainability-dashboard/supply-chain-map' page = requests.get(url).content soup = BeautifulSoup(page, "html.parser") # 匹配var locations = 开头的完整数组,re.DOTALL让.匹配换行符 pattern = re.compile(r'var locations = (\[.*?\]);', re.DOTALL) locations_data = None # 遍历所有script标签,寻找目标变量 for script in soup.find_all("script"): script_text = script.string if script_text: match = pattern.search(script_text) if match: # 将JS数组字符串转为Python列表(可信网站下用eval安全,也可替换为json.loads做更安全处理) locations_data = eval(match.group(1)) break if not locations_data: print("未能找到目标locations变量,请检查页面结构是否更新") else: print(f"成功提取到 {len(locations_data)} 条设施数据") # 创建PDF保存文件夹 pdf_save_dir = "goldenagri_facility_pdfs" os.makedirs(pdf_save_dir, exist_ok=True) # 准备存储数据的列表 facility_list = [] for item in locations_data: # 提取核心字段(对应你提供的目标变量结构) facility = item.get('facility', '') company = item.get('company', '') location = item.get('location', '') lat = item.get('lat') lng = item.get('lng') pdf_relative_link = item.get('pdf', '') # 下载PDF(如果存在链接) if pdf_relative_link: full_pdf_url = urljoin(url, pdf_relative_link) # 处理文件名中的特殊字符,避免保存失败 safe_filename = f"{facility.replace('/', '_').replace(':', '_')}.pdf" pdf_path = os.path.join(pdf_save_dir, safe_filename) try: urllib.request.urlretrieve(full_pdf_url, pdf_path) print(f"已成功下载: {pdf_path}") except Exception as e: print(f"下载PDF失败 [{full_pdf_url}]: {str(e)}") # 将数据添加到列表 facility_list.append({ '设施名称': facility, '公司名称': company, '地点': location, '纬度': lat, '经度': lng, 'PDF原链接': pdf_relative_link }) # 生成DataFrame并导出到Excel df = pd.DataFrame(facility_list) df.to_excel('goldenagri_supply_chain_data.xlsx', index=False) print("数据已成功导出到 goldenagri_supply_chain_data.xlsx")
注意事项
- 依赖库安装:确保你已经安装了所需的库,执行以下命令安装:
其中pip install requests beautifulsoup4 pandas openpyxlopenpyxl是Pandas导出Excel所需的依赖。 - 安全提示:代码中用
eval解析JS数组,因为目标网站是可信的,所以没问题。如果是处理未知来源的代码,建议把匹配到的字符串中的单引号替换成双引号,再用json.loads解析,避免安全风险。 - 页面结构变化:如果后续网站更新了页面结构,可能需要调整正则表达式来适配新的变量定义。
内容的提问来源于stack exchange,提问作者Funkeh-Monkeh
相关产品推荐
相关产品推荐

