【发布时间】:2021-09-20 14:49:31
【问题描述】:
所以我有这个脚本,它将数据抓取到网站,它获取和下载 CSV,并逐行处理 CSV 并将其转换为 TSV,一旦完成,TSV 文件将转换为 HTML 文件。我已经完成了其余的工作,但是我得到的输出有些混乱,脚本转到源站点上的不同表格页面并下载动态生成的 CSV 文件;然后将该 CSV 文件转换为 TSV 文件,然后我们将其转换为 HTML。 CSV 文件似乎按返回的每一行的第一列排序,但不基于同一行中的任何其他列。因此,第一列值相同的条目可能会从一次下载到同一文件的下一次下载混为一谈。
仅按第一列排序的直观表示,后面是表示列数据的数字:
第一次下载: 1-1 1-2 1-3 2-1 2-2 2-3 3-1 3-2 3-3
第二次下载: 1-1 1-3 1-2 2-2 2-1 2-3 3-3 3-2 3-1
所以我想到的过程是这样的,从源下载 CSV 文件,然后对该 CSV 文件中的行进行排序,以便在编写 TSV 或 HTML 之前将它们标准化以便相互比较文件。这应该允许对更新的数据文件进行准确比较。但我不知道该怎么做我的逻辑是这样的
所以在将 CSV 文件处理为 TSV 文件之前,我会将函数放在 1. 和 2. 之间,我希望 CSV 的内容已经排序。
所以我的脚本是这样的
my $download_dir_link ="C:/Users/jabella/Downloads";
unlink("$download_dir_link/Product Classification List.csv");
#CHECK IF CSV FILE DOWNLOAD IS FINISHED
my $complete_download_flag = 0;
while($complete_download_flag == 0)
{
my @download_directory = read_dir($download_dir_link);
foreach my $downloaded_file (@download_directory)
{
if($downloaded_file =~ /\QProduct Classification List.csv\E/sgi)
{
$complete_download_flag = 1;
}
}
sleep(5);
}
#SORTED CONTENTS OF CSV BEFORE CONVERSION
print "sORTING csv content...\n";
#CONVERT CSV TO TSV
print "Converting csv to tsv...\n";
my $csv = Text::CSV->new ({ binary => 1 });
my $tsv = Text::CSV->new ({ binary => 1, sep_char => "\t", eol => "\n"});
open my $infh, "<:encoding(utf8)", "$download_dir_link/Product Classification List.csv";
open my $outfh, ">:encoding(utf8)", "Product Classification List.tsv";
while (my $row = $csv->getline ($infh))
{
$tsv->print ($outfh, $row);
}
close($infh);
close($outfh);
my $tsv_content = "";
open(my $fh, '<', "Product Classification List.tsv");
while (<$fh>)
{
$tsv_content = $tsv_content.$_;
}
close($fh);
print "Conversion complete! cleaning tsv content...\n";
#CLEAN TSV CONTENT
$tsv_content =~ s/(.*?)\t"(.*?)"\t"(.*?)"\t"(.*?)"\t(.*?)\t"(.*?)"\t(.*)/<tr><th>$1<\/th><th>$2<\/th><th>$3<\/th><th>$4<\/th><th>$5<\/th><th>$6<\/th><th>$7<\/th><\/tr>/gi;
$tsv_content =~ s/"?(.*?)"?\t"?(.*?)"?\t"?(.*?)"?\t"?(.*?)"?\t"?(.*?)"?\t"?(.*?)"?\t"?(.*?)"?\n/<tr><td>$1<\/td><td>$2<\/td><td>$3<\/td><td>$4<\/td><td>$5<\/td><td>$6<\/td><td>$7<\/td><\/tr>\n/gi;
$tsv_content =~ s/\"{2}/\"/sgi;
$tsv_content =~ s/(<\/tr>)\n?"/$1/sgi;
$tsv_content =~ s/\s{2,}/ /sgi;
$tsv_content =~ s/.*?(<tr>)/$1/si;
$tsv_content = "<table>\n$tsv_content</table>";
$classification =~ s/_//sgi;
if(exists $existing_index_hash{$doc_uid."_pind.html"})
{
if($existing_index_hash{$doc_uid."_pind.html"} ne $tsv_content)
{
$changed_flag = "1";
$updated_files = $updated_files."-$classification\n";
print "Updated: $classification\n";
希望有人能帮我解决这个问题,谢谢
【问题讨论】:
-
您发布的大部分代码与问题无关。
-
另外,你真的需要哈希吗?如果要保持原始顺序,请使用数组。
-
我展示的是我所做的功能,我现在缺少的是在将CSV文件转换为TSV文件之前将CSV文件的内容排序为升序的功能
-
我只是想到那个,我真的不知道如何创建那个函数。 :( 所以任何帮助都会做
-
没有示例 CSV,我无法运行您的代码来使用它。