FishC
发表于 2024-7-18 09:59:45
wp231957 发表于 2024-07-18 09:59
发现秘密了
这些个表格内容虽然在当前页面中已经渲 ...
这就有趣了!你发现了网页中的内容嵌套在`iframe`中。在这种情况下,我们需要先访问`iframe`的内容,然后再从`iframe`中提取所需的信息。
我们可以通过以下代码来处理`iframe`:
// ==UserScript==
// @name 导出网页信息到文件
// @namespace http://tampermonkey.net/
// @version 0.1
// @description导出当前网页中的部分信息到CSV文件
// @author wp231957
// @match *://*/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 创建导出按钮
const button = document.createElement('button');
button.textContent = '导出表格数据';
button.style.position = 'fixed';
button.style.top = '10px';
button.style.right = '10px';
button.style.zIndex = 1000;// 确保按钮在其它元素之上
document.body.appendChild(button);
button.addEventListener('click', () => {
// 获取iframe内容
const iframe = document.getElementById('iframe0');
if (iframe) {
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
// 找到你需要的表格和列,比如提取第1,2,3列(索引从0开始)
const rows = Array.from(iframeDocument.querySelectorAll('table tbody tr'));
// 调试用弹窗,检查提取到的行
alert('提取到的行数: ' + rows.length);
const data = rows.map(row => {
const cells = row.querySelectorAll('td');
return cells ? .textContent, cells.textContent, cells.textContent] : ['', '', '']; // 提取第1,2和第3列
});
// 将数据转换为CSV格式
const csvContent = "data:text/csv;charset=utf-8," + data.map(e => e.join(",")).join("\n");
// 创建下载链接
const encodedUri = encodeURI(csvContent);
const link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "table_data.csv");
document.body.appendChild(link);
// 点击下载链接
link.click();
// 清除下载链接
document.body.removeChild(link);
} else {
alert('未找到 iframe 内容');
}
});
})();
这个脚本做了以下几件事:
1. 创建一个按钮并添加到页面中。
2. 当点击按钮时,获取`iframe`的内容。
3. 从`iframe`中找到指定的表格数据。
4. 将表格数据转换为CSV格式并生成下载链接。
请确保你的`iframe`的id是正确的。如果你的`iframe`在JavaScript加载后是动态创建的,你可能还需要等到`iframe`加载完成后再执行这些操作。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
wp231957
发表于 2024-7-18 10:01:42
FishC 发表于 2024-7-18 09:59
这就有趣了!你发现了网页中的内容嵌套在`iframe`中。在这种情况下,我们需要先访问`iframe`的内容,然 ...
不是的,iframe下面没有表格内容而是一个类似html链接的玩意类似https://xxxx/xxxxx/xxxx/xxx!xxx.do
FishC
发表于 2024-7-18 10:02:16
wp231957 发表于 2024-07-18 10:01
不是的,iframe下面没有表格内容而是一个类似html链 ...
明白了,`iframe` 的 `src` 属性指向了一个不同的 URL,其中实际加载了你需要的数据。这种情况需要处理 `iframe` 的内容。这是我们可以通过跨域策略来解决的一种特殊情况。
**注意:** 浏览器出于安全原因,通常禁止跨域访问 `iframe` 内容。这意味着,如果 `iframe` 的内容与主页面的域名不同,直接访问 `iframe` 内容会受到限制。
### 步骤:
1. **加载 `iframe` 页面内容:**
首先我们需要等待 `iframe` 加载完成。
2. **访问 `iframe` 的文档:**
然后我们需要从 `iframe` 中提取所需的数据。
下面是一个示例代码,尝试处理 `iframe` 内容:
// ==UserScript==
// @name 导出网页信息到文件
// @namespace http://tampermonkey.net/
// @version 0.1
// @description导出当前网页中的部分信息到CSV文件
// @author wp231957
// @match *://*/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 创建导出按钮
const button = document.createElement('button');
button.textContent = '导出表格数据';
button.style.position = 'fixed';
button.style.top = '10px';
button.style.right = '10px';
button.style.zIndex = 1000;// 确保按钮在其它元素之上
document.body.appendChild(button);
button.addEventListener('click', () => {
const iframe = document.getElementById('iframe0');
if (!iframe) {
alert('未找到 iframe');
return;
}
// 监听 iframe 加载完成
iframe.addEventListener('load', () => {
try {
// 尝试访问 iframe 内容
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
const rows = Array.from(iframeDocument.querySelectorAll('table tbody tr'));
if (rows.length === 0) {
alert('未找到表格数据');
return;
}
// 提取第1, 2, 3列(索引从0开始)
const data = rows.map(row => {
const cells = row.querySelectorAll('td');
return ?.textContent || '', cells?.textContent || '', cells?.textContent || ''];
});
// 将数据转换为CSV格式
const csvContent = "data:text/csv;charset=utf-8," + data.map(e => e.join(",")).join("\n");
// 创建下载链接
const encodedUri = encodeURI(csvContent);
const link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "table_data.csv");
document.body.appendChild(link);
// 点击下载链接
link.click();
// 清除下载链接
document.body.removeChild(link);
} catch (error) {
alert('无法访问 iframe 内容,可能是跨域限制');
console.error('错误:', error);
}
});
});
})();
### 注意事项:
- 代码通过监听 `iframe` 的 `load` 事件,确保在 `iframe` 加载完成后再访问其内容。
- 尝试访问 `iframe` 的内容时,如果遇到跨域问题,浏览器会抛出错误。你可以在控制台中查看详细的错误信息。
如果仍然遇到问题,可以考虑其他方法,例如通过后台服务器进行数据提取,或者与网站管理员沟通以获得数据访问权限。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
wp231957
发表于 2024-7-18 10:04:33
FishC 发表于 2024-7-18 10:02
明白了,`iframe` 的 `src` 属性指向了一个不同的 URL,其中实际加载了你需要的数据。这种情况需要处理 ...
主域名一样(就是紧挨着HTTPS的) 这不算跨域吧
FishC
发表于 2024-7-18 10:04:58
wp231957 发表于 2024-07-18 10:04
主域名一样(就是紧挨着HTTPS的) 这不算跨域吧
如果主域名相同,这确实不算跨域。在这种情况下,我们可以访问和操作 `iframe` 的内容。下面是一个如何从 `iframe` 中提取表格数据的示例:
// ==UserScript==
// @name 导出网页信息到文件
// @namespace http://tampermonkey.net/
// @version 0.1
// @description导出当前网页中的部分信息到CSV文件
// @author wp231957
// @match *://*/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 创建导出按钮
const button = document.createElement('button');
button.textContent = '导出表格数据';
button.style.position = 'fixed';
button.style.top = '10px';
button.style.right = '10px';
button.style.zIndex = 1000; // 确保按钮在其它元素之上
document.body.appendChild(button);
button.addEventListener('click', () => {
// 获取 iframe 元素
const iframe = document.getElementById('iframe0');
if (!iframe) {
alert('无法找到 iframe!');
return;
}
// 尝试访问 iframe 内容
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
if (!iframeDoc) {
alert('无法访问 iframe 的内容!');
return;
}
const rows = Array.from(iframeDoc.querySelectorAll('table tbody tr'));
alert('提取到的行数: ' + rows.length);
// 找到你需要的表格和列,比如提取第1, 2, 3列(索引从0开始)
const data = rows.map(row => {
const cells = row.querySelectorAll('td');
return ? cells.textContent : '', cells ? cells.textContent : '', cells ? cells.textContent : '']; // 提取第1, 2和第3列
});
// 将数据转换为CSV格式
const csvContent = "data:text/csv;charset=utf-8," + data.map(e => e.join(",")).join("\n");
// 创建下载链接
const encodedUri = encodeURI(csvContent);
const link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "table_data.csv");
document.body.appendChild(link);
// 点击下载链接
link.click();
// 清除下载链接
document.body.removeChild(link);
});
})();
这段代码大致包含以下几个步骤:
1. **创建导出按钮**:创建按钮并添加到页面。
2. **按钮点击事件处理**:在点击按钮时进入事件处理器。
3. **获取 iframe 内容**:获取 `iframe` 元素,并尝试访问其内容。
4. **提取表格数据**:从 `iframe` 中提取目标表格的行和列数据。
5. **转换数据格式并下载**:将提取的数据转换成 CSV 格式,并自动下载。
在 `iframeDoc.querySelectorAll('table tbody tr')` 中,你可以根据实际情况调整选择器来准确定位需要提取的表格。希望这个脚本能够满足你的需求!如果有任何问题,欢迎继续交流!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
wp231957
发表于 2024-7-18 10:11:29
FishC 发表于 2024-7-18 10:04
如果主域名相同,这确实不算跨域。在这种情况下,我们可以访问和操作 `iframe` 的内容。下面是一个如何 ...
请接受我的感谢,终于完美实现了
FishC
发表于 2024-7-18 10:11:42
wp231957 发表于 2024-07-18 10:11
请接受我的感谢,终于完美实现了
太好了,很高兴听到你的问题解决了!如果你还有其他问题或者需要进一步的帮助,随时告诉我。祝你使用愉快!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
wp231957
发表于 2024-7-18 10:14:10
FishC 发表于 2024-7-18 10:11
太好了,很高兴听到你的问题解决了!如果你还有其他问题或者需要进一步的帮助,随时告诉我。祝你使用愉 ...
有的,因为该表格页面有15页,所以我会导出15个csv 或者xls
那么我下一步就要把这15个表格合成一个大表 这15个表的表头是一样的
FishC
发表于 2024-7-18 10:14:23
wp231957 发表于 2024-07-18 10:14
有的,因为该表格页面有15页,所以我会导出15个csv 或 ...
好的,我明白你的需求了。你现在需要将这15个表格合并成一个大表格。为了做到这一点,你可以使用Python,非常方便。下面是一个简单的脚本,可以帮助你合并这些CSV文件:
首先,你需要安装 `pandas` 库,如果你还没有安装过的话。打开命令行或终端,运行以下命令:
pip install pandas
然后,在Python中编写以下代码:
import os
import pandas as pd
# 假设所有的 CSV 文件都在一个名为 'csv_files' 的文件夹中
folder_path = 'csv_files'
# 获取该文件夹中所有的 CSV 文件名
csv_files =
# 用 pandas 读取所有 CSV 文件并合并它们
dfs =
# 使用 pandas.concat() 方法将所有 DataFrame 合并成一个
merged_df = pd.concat(dfs, ignore_index=True)
# 将合并后的 DataFrame 保存为新的 CSV 或 Excel 文件
merged_csv_path = 'merged_file.csv'
merged_xlsx_path = 'merged_file.xlsx'
merged_df.to_csv(merged_csv_path, index=False)
merged_df.to_excel(merged_xlsx_path, index=False)
print(f'合并后的 CSV 文件已保存到: {merged_csv_path}')
print(f'合并后的 Excel 文件已保存到: {merged_xlsx_path}')
1. **`folder_path`**: 这个变量应该是包含所有 CSV 文件的文件夹路径。
2. **读取 CSV 文件**: 我们使用 `os.listdir` 来获取该文件夹中所有的 CSV 文件名,然后使用 `pandas.read_csv` 读取每个文件。
3. **合并文件**: 我们使用 `pandas.concat` 方法将所有 DataFrame 合并成一个大的 DataFrame。
4. **保存文件**: 最后将合并后的 DataFrame 保存为一个新的 CSV 文件和一个新的 Excel 文件。
通过以上步骤,你就能轻松地将15个表格合并成一个大表格了。如果你还有其他问题,随时告诉我!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
wp231957
发表于 2024-7-18 10:26:53
FishC 发表于 2024-7-18 10:14
好的,我明白你的需求了。你现在需要将这15个表格合并成一个大表格。为了做到这一点,你可以使用Python ...
如果我再针对其他网页再写一个油猴脚本,那么我该怎么做比较好一些呢
在那个导出表格按钮后面再追加一个按钮还是使用一个油猴时 就屏蔽另一个油猴
FishC
发表于 2024-7-18 10:27:13
wp231957 发表于 2024-07-18 10:26
如果我再针对其他网页再写一个油猴脚本,那么我该怎么 ...
如果你想在一个网页上添加多个功能,你有几种选择可以考虑:
1. **在同一个油猴脚本中添加多个功能**:
- 可以在现有的油猴脚本中添加新的功能,例如在导出表格按钮后面追加一个按钮。这种方式适合功能相关性较强或者互不冲突的情况。
2. **编写多个油猴脚本**:
- 如果功能之间较为独立或者可能会相互干扰,可以为每个功能编写单独的油猴脚本。这样可以更好地管理和调试每个功能,避免潜在的冲突。
3. **考虑使用模块化的方式**:
- 如果你需要在不同网页上重复使用一些功能,可以将这些功能封装成模块,然后在不同的油猴脚本中引入这些模块。这样可以提高代码复用性和维护性。
4. **注意脚本加载顺序和冲突**:
- 如果你决定在同一个油猴脚本中添加多个功能,要注意脚本加载的顺序和可能的冲突。确保各功能之间的逻辑和资源不会相互干扰或覆盖。
根据具体情况选择适合你需求的方式,这样能帮助你更高效地开发和管理油猴脚本。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
wp231957
发表于 2024-7-18 11:01:33
FishC 发表于 2024-7-18 10:14
好的,我明白你的需求了。你现在需要将这15个表格合并成一个大表格。为了做到这一点,你可以使用Python ...
不行啊 这个代码合并后的excel表没法看啊 全都错位了
根本就不是一个标准的二维表
import os
import pandas as pd
folder_path = r'd:\\wp\\csv'
csv_files =
dfs =
merged_df = pd.concat(dfs, ignore_index=True)
merged_xlsx_path = '142.xlsx'
merged_df.to_excel(merged_xlsx_path, index=False)
print(f'合并后的 Excel 文件已保存到: {merged_xlsx_path}')
FishC
发表于 2024-7-18 11:02:55
wp231957 发表于 2024-07-18 11:01
不行啊 这个代码合并后的excel表没法看啊 全都 ...
好的,合并CSV文件为一个标准的Excel表格,涉及到读取各个CSV文件并进行正确的拼接。下面是一个完整的Python脚本,确保CSV文件都是标准的二维表:
import os
import pandas as pd
# 文件夹路径
folder_path = r'd:\\wp\\csv'
# 获取文件夹下所有的csv文件
csv_files =
# 用于存储每个CSV文件的数据帧
dfs = []
# 遍历每个csv文件
for csv_file in csv_files:
# 构造完整的文件路径
file_path = os.path.join(folder_path, csv_file)
# 读取csv文件
df = pd.read_csv(file_path)
# 添加到数据帧列表中
dfs.append(df)
# 合并所有的数据帧
merged_df = pd.concat(dfs, ignore_index=True)
# 合并后的Excel文件路径
merged_xlsx_path = os.path.join(folder_path, 'merged_output.xlsx')
# 将合并后的数据帧保存为Excel文件
merged_df.to_excel(merged_xlsx_path, index=False)
print(f'合并后的 Excel 文件已保存到: {merged_xlsx_path}')
### 确保CSV文件格式一致
在运行这个脚本之前,确保你的所有CSV文件都具有相同的结构,即相同的列数和相同的列名。如果列名或列数不一致,会导致合并后的数据框出现问题。
### 运行脚本
1. 确保你已经安装了pandas库。如果没有安装,可以使用以下命令安装:
pip install pandas
2. 将上述代码保存为一个Python文件,例如 `merge_csv_to_excel.py`。
3. 在终端或命令行中运行这个Python文件:
python merge_csv_to_excel.py
运行后,你将在指定文件夹中看到合并后的Excel文件 `merged_output.xlsx`。这样,你的所有CSV文件内容就会被正确地合并到一个Excel文件中。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
wp231957
发表于 2024-7-18 13:34:28
FishC 发表于 2024-7-18 11:02
好的,合并CSV文件为一个标准的Excel表格,涉及到读取各个CSV文件并进行正确的拼接。下面是一个完整的P ...
两点,
1、我的文件是无标题行的,但是pandas把第一行当做默认的标题行 这个要去除
2、文件与文件之间缺少一个换行回车
以上两点 导致合并后的文件非常之混乱
FishC
发表于 2024-7-18 13:34:52
wp231957 发表于 2024-07-18 13:34
两点,
1、我的文件是无标题行的,但是pandas把第一 ...
好的,理解了你的问题。我们可以通过以下步骤来解决:
1. 告诉 `pandas` 不要把第一行当作标题行。
2. 在合并数据时,确保文件之间适当分隔。
下面是一个更新后的代码示例:
import os
import pandas as pd
folder_path = r'd:\\wp\\csv'
csv_files =
dfs = []
for csv_file in csv_files:
file_path = os.path.join(folder_path, csv_file)
df = pd.read_csv(file_path, header=None)# 设置header=None以将第一行视为数据行
dfs.append(df)
# 添加换行回车分隔符
dfs_with_sep = []
for i, df in enumerate(dfs):
# 为每个df添加一个空行,以便分隔文件
dfs_with_sep.append(df)
if i < len(dfs) - 1:# 在每个文件之间加入一个空行,但不在最后一个文件后加入
sep_df = pd.DataFrame([''] * df.shape).transpose()# 构建一个包含空值的DataFrame
dfs_with_sep.append(sep_df)
merged_df = pd.concat(dfs_with_sep, ignore_index=True)
merged_xlsx_path = '142.xlsx'
merged_df.to_excel(merged_xlsx_path, index=False, header=False)# 生成Excel文件,并取消标题行
print(f'合并后的 Excel 文件已保存到: {merged_xlsx_path}')
在这个代码中:
1. `header=None` 确保 `pandas` 将所有行都视为数据行,而不是标题行。
2. 在每两个CSV文件之间插入一个只含空值的行分隔符(空 DataFrame),这会帮助你在合并后的表格中更容易地区分不同源文件的数据。
这样,合并后的Excel文件应该更加整洁,不再出现数据错位的问题。希望这个解决方案能帮到你!如果有任何其他问题,尽管问哦~
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
wp231957
发表于 2024-7-18 13:41:00
FishC 发表于 2024-7-18 13:34
好的,理解了你的问题。我们可以通过以下步骤来解决:
1. 告诉 `pandas` 不要把第一行当作标题行。
...
这次 好多了
可不可以添加两项需求
1、它给我添加了一个默认表头内容是 012
要求 要么不加表头要么我自己设定表头内容
2、前面第一列是序号列 可不可以从1---末尾从小到大排序
FishC
发表于 2024-7-18 13:41:14
wp231957 发表于 2024-07-18 13:41
这次 好多了
可不可以添加两项需求
1、它给我添加了 ...
明白了,接下来我们继续改进代码以满足新需求:
1. 可以通过在 `read_csv` 方法中设置 `header=None` 来确保 `pandas` 不自动生成表头,然后再手动添加表头或保持无表头。
2. 在合并后的数据框中添加一个序号列,并按照1到末尾的顺序排列。
下面是更新后的解决方案:
import os
import pandas as pd
folder_path = r'd:\\wp\\csv'
csv_files =
dfs = []
# 手动设定表头
custom_header = ['你的自定义列名1', '你的自定义列名2', '你的自定义列名3']
for file in csv_files:
df = pd.read_csv(os.path.join(folder_path, file), header=None)
dfs.append(df)
# 合并 DataFrame 并重置索引
merged_df = pd.concat(dfs, ignore_index=True)
# 添加自定义或无表头
if custom_header:
merged_df.columns = custom_header
# 添加序号列,从 1 开始
merged_df.insert(0, '序号', range(1, len(merged_df) + 1))
# 保存为 Excel 文件
merged_xlsx_path = '142.xlsx'
merged_df.to_excel(merged_xlsx_path, index=False)
print(f'合并后的 Excel 文件已保存到: {merged_xlsx_path}')
需要注意以下几点:
1. 使用 `header=None` 确保不自动生成表头。
2. 设置 `custom_header` 变量来自定义列名,如果你想保持无表头,可以将 `custom_header` 设置为 `None` 或者空列表。
3. 插入了一个序号列从1到末尾。
希望这些调整能够满足您的需求!有什么问题可以随时问哦。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
wp231957
发表于 2024-7-18 13:47:17
FishC 发表于 2024-7-18 13:41
明白了,接下来我们继续改进代码以满足新需求:
1. 可以通过在 `read_csv` 方法中设置 `header=None ...
merged_df.insert(0, '序号', range(1, len(merged_df) + 1)) 出错了提示 序号已经存在
实际上 我也不需要插入操作,我需要的是对序号列 重新赋值按从小到大 从1 开始
或者干脆删除序号列 ,重新插入 也是可以的
FishC
发表于 2024-7-18 13:47:40
wp231957 发表于 2024-07-18 13:47
merged_df.insert(0, '序号', range(1, len(merged_df ...
好的,明白了。我们可以对已经存在的序号列重新赋值,或者删除现有的序号列然后重新插入。下面是解决这两个问题的代码示例:
1. 删除默认表头并设定自己的表头。
2. 删除现有的序号列并重新插入一个新的从1开始的序号列。
import pandas as pd
import glob
# 获取所有csv文件路径
file_paths = glob.glob("path/to/your/files/*.csv")
# 创建一个空的DataFrame
merged_df = pd.DataFrame()
# 遍历所有文件
for file_path in file_paths:
df = pd.read_csv(file_path, header=None)
# 将当前文件的数据添加到merged_df中
merged_df = pd.concat(, ignore_index=True)
# 删除现有的表头(如果有)
merged_df.columns = ['col1', 'col2', 'col3']# 设置自己的表头,可以根据需要更改
# 删除现有的序号列(如果有)
if '序号' in merged_df.columns:
merged_df = merged_df.drop(columns=['序号'])
# 添加一个新的从1开始的序号列
merged_df.insert(0, '序号', range(1, len(merged_df) + 1))
# 保存合并后的文件
merged_df.to_csv('path/to/save/merged_file.csv', index=False)
这段代码完成以下几步:
1. 加载所有CSV文件,并去除默认表头。
2. 使用你指定的列名作为表头。
3. 删除现有的序号列(如果有)。
4. 插入一个新的序号列,从1开始,按顺序编号。
5. 将合并后的DataFrame保存到新的CSV文件中。
注意:请根据你的文件实际路径和列名调整代码中的路径和列名。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
wp231957
发表于 2024-7-18 13:51:03
FishC 发表于 2024-7-18 13:47
好的,明白了。我们可以对已经存在的序号列重新赋值,或者删除现有的序号列然后重新插入。下面是解决这 ...
good
再添加一些
1.A B C 三列自适应宽度
2、为表格有数据区域添加表格框线