如何用Python操作动态数据表并抓取指定网站的炼油厂数据?
抓取SONRIS炼油厂R3报告数据的Python实现方案
一、Selenium方案(适配动态交互场景)
该网站交互步骤较多,Selenium模拟真实浏览器操作是最直接的方式,适合处理导航、日期输入这类页面交互。
1. 安装依赖
先安装Selenium及对应浏览器驱动(以Chrome为例):
pip install selenium
ChromeDriver需与本地Chrome版本匹配,可放在系统PATH目录或在代码中指定路径。
2. 完整代码示例
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.action_chains import ActionChains import time # 初始化Chrome浏览器 driver = webdriver.Chrome() driver.get("https://sonlite.dnr.state.la.us") driver.maximize_window() try: # 1. 点击SONRIS Data Portal入口 portal_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.LINK_TEXT, "SONRIS Data Portal")) ) portal_btn.click() # 2. 触发Production Audit下拉菜单(鼠标悬停) production_audit = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.LINK_TEXT, "Production Audit")) ) ActionChains(driver).move_to_element(production_audit).perform() # 3. 点击R3报告的表格图标 r3_report = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'R3 (Refinery) Activity Report Product Listing IDR')]/following-sibling::img[@alt='Table']")) ) r3_report.click() # 4. 切换到新打开的标签页 driver.switch_to.window(driver.window_handles[-1]) # 5. 输入起止日期(需匹配页面日期格式,示例为MM/DD/YYYY) start_date = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "startDate")) ) start_date.clear() start_date.send_keys("01/01/2023") end_date = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "endDate")) ) end_date.clear() end_date.send_keys("12/31/2023") # 6. 提交查询 submit_btn = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "submitButton")) ) submit_btn.click() # 7. 提取结果表格数据 time.sleep(5) # 或用WebDriverWait等待表格加载完成 table = WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.TAG_NAME, "table")) ) rows = table.find_elements(By.TAG_NAME, "tr") for row in rows: cols = row.find_elements(By.TAG_NAME, "td") row_data = [col.text for col in cols] print(row_data) # 可替换为保存到CSV/数据库的逻辑 finally: driver.quit()
关键注意点
- 元素定位(ID、XPATH等)需用浏览器F12开发者工具确认,网站更新后可能需要调整
- 若遇到登录/验证码拦截,需补充对应处理逻辑
- 日期格式必须严格匹配页面要求,否则查询会失败
二、Requests方案(高效抓API接口)
若能定位到查询的后端API,用requests效率远高于Selenium,步骤如下:
1. 抓包分析请求
- 打开浏览器F12→Network标签
- 按操作路径打开R3报告页面,输入日期并提交查询
- 在Network列表中筛选XHR/Fetch请求,找到查询接口的URL、请求方法、参数及Headers(重点关注Cookie、User-Agent、CSRF Token等)
2. 代码示例(假设抓包得到的接口参数)
import requests import pandas as pd # 抓包获取的请求头(Cookie需保持有效,过期后需重新抓取) 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", "Cookie": "替换为抓包得到的Cookie", "Referer": "https://sonlite.dnr.state.la.us/xxx" # 替换为实际Referer } # 查询参数(需与抓包结果一致) payload = { "startDate": "01/01/2023", "endDate": "12/31/2023", "reportType": "R3" } # 发送请求 response = requests.post("https://sonlite.dnr.state.la.us/api/r3-report", headers=headers, data=payload) # 解析并保存数据 if response.status_code == 200: # 若返回JSON格式 data = response.json() df = pd.DataFrame(data) df.to_csv("refinery_r3_data.csv", index=False) print("数据保存成功") # 若返回HTML表格,用pandas直接解析 # df = pd.read_html(response.text)[0] else: print(f"请求失败,状态码:{response.status_code}")
关键注意点
- Cookie会定期过期,可先用Selenium登录获取Cookie后传给requests复用
- 部分网站会校验CSRF Token,需从页面HTML中提取后加入请求参数/Headers
- 若接口有签名验证,需逆向分析签名生成逻辑(复杂度较高)
内容的提问来源于stack exchange,提问作者jare2620
相关产品推荐
相关产品推荐

