我正在努力通过美国第七巡回上诉法院并获取 RSS 链接以进行监控并自动下载司法意见的 pdf 文件。
当前的系统给我带来了问题。幸运的是,我能够使用以下链接让系统转储(输出)1999 年 10 月 28 日至 2020 年 12 月 30 日期间的所有 15,967 条司法意见:
每个案例的文档下载链接的结构如下:
我不太熟悉 cgi-bin / .pl rss 配置和系统。
我使用以下 Mozilla Firefox 扩展程序一次大量打开 1000 个意见:
快照链接:https://addons.mozilla.org/en-US/firefox/addon/snaplinksplus/
网址列表:https://addons.mozilla.org/en-US/firefox/addon/urls-list/
我对此的看法是一次公开 1,000 个意见。构建一个链接列表,然后针对我要将它们粘贴到的 .txt 文件运行大量 WGET 查询。
但是,当手动使用 CURL 时,它是获取文件和 WGET 的最基本语法,我尝试下载以下单一司法意见失败:
WGET 尝试:
brandon@icedragon:~/CURL/7thCir.1/WGET.1$ wget (LINK5)
After Enter in Terminal:
[2] 3130
brandon@icedragon:~/CURL/7thCir.1/WGET.1$
Redirecting output to ‘wget-log’.
brandon@icedragon:~/CURL/7thCir.1/WGET.1$ ls
'rssExec.pl?Submit=Display' wget-log
brandon@icedragon:~/CURL/7thCir.1/WGET.1$ tail -f wget-log
Resolving media.ca7.uscourts.gov (media.ca7.uscourts.gov)... 63.241.41.178
Connecting to media.ca7.uscourts.gov (media.ca7.uscourts.gov)|63.241.41.178|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/pdf]
Saving to: ‘rssExec.pl?Submit=Display’
rssExec.pl?Submit [ <=> ] 0 --.-KB/s in 0s
2020-12-30 18:27:27 (0.00 B/s) - ‘rssExec.pl?Submit=Display’ saved [0]
CURL 尝试:
brandon@icedragon:~/CURL/7thCir.1/CURL.1$ curl (LINK5)
After Enter in Terminal:
[2] 3154
brandon@icedragon:~/CURL/7thCir.1/CURL.1$ ls
[2]- Done
brandon@icedragon:~/CURL/7thCir.1/CURL.1$ ls
brandon@icedragon:~/CURL/7thCir.1/CURL.1$
如果有人有任何建议;我最初希望将 RSS 带入 Thunderbird,然后最终将 RSS 链接复制到 PHP 中,并以某种方式让 Python 管理数据,然后将其传回给 PHP。 (最终目标更大)。
答案 0 :(得分:1)
人们已经表明你的第一个错误是没有保护 shell 元字符。命令行上的 &
告诉 shell 将作业置于后台。 [2] 3154
是括号中的作业号和进程 ID。用命令周围的引号修复它:
% curl '...url...'
这让您可以提出请求,但现在的诀窍是获取文件名。这个特殊的例子让它有点难:
简而言之,您发出请求,并不关心 URL 的样子。您不必了解有关远程服务器、Perl 等的任何信息。您提出请求并获得响应。由您来处理响应。
在这种情况下,您正在点击一个提供 PDF 响应的脚本。但是,它可能会返回其他内容。
在这样的响应中,Content-Disposition
可以建议文件名。通常,curl
可以通过使用 -O
开关(另请参阅 How do I save a file using the response header filename with cURL?)使用建议的文件名为您保存文件(-J
):
% curl -J -O '...'
显然,此服务未使用 Content-Disposition
,因此您无法从中获取文件名:
$ curl -i 'http://media.ca7.uscourts.gov/cgi-bin/rssExec.pl?Submit=Display&Path=Y2019/D06-24/C:18-2169:J:Brennan:aut:T:fnOp:N:2360043:S:0'
HTTP/1.1 200 OK
Date: Thu, 31 Dec 2020 17:40:27 GMT
Server: Apache/2.4.37 (Red Hat Enterprise Linux) OpenSSL/1.1.1g
Transfer-Encoding: chunked
Content-Type: application/pdf
如果没有建议的文件名,curl -J -O
会创建一个类似于 C:20-1779:J:Flaum:aut:T:fnOp:N:2636910:S:0
的文件名,这对您来说可能已经足够了。案例编号、日期和作者都在那里。您可能想在那里添加一个 .pdf
。
您可以对该文件名进行后处理以缩短一些内容。案例编号可能足够好,例如 20-1779.pdf
。
在您完成此部分之前,请注意这可能不是完成此任务的可持续方法。 GovInfo has APIs 为您提供所需的东西,这样您就不必依赖特定线路的服务。
但无论如何我们还是要这样做,因为它对一般任务很有指导意义,而且很容易。你想为这些东西建立一个数据库,所以当你向人们展示这些东西时,你可能需要这些信息。 (请注意,如果这就是您正在做的事情,那么您实际上是在接受 PACER,而他们对这类事情并不是特别友好)。
请注意,该链接包含许多可能对文件名感兴趣的信息。案例编号、日期和作者都在那里。其他字母可能有意义,所以看起来您只是缺少标题。
您有包含案例名称的起始表(绝对不是 RSS)。我会解析该表,将案例名称与下载链接相关联,然后保存响应并根据需要重命名。
我不使用那些 Mozilla 扩展,所以我不知道你会如何使用它们来解决这个问题。
我确实用 Perl 编写了这个 Mojolicious 程序,其他编程语言也有类似的工具(Python 有 BeautifulSoup,可能还有其他的)。我在 Mojo Web Clients 中写过这些东西。那本书不仅解释了工具,还解释了正在发生的事情以及为什么你必须以某种方式做事。
我在 HTML 的 DOM 中导航以找到正确的表格行,然后提取表格列。他们的 HTML 并不复杂(没有类或 ID),但至少我可以识别正确的表和行。这很脆弱,因为如果他们更改 HTML 就会中断。
我把所有情况下的大数据结构。我选择的表格并不重要,您可以随心所欲地制作它,甚至可以立即将其插入到您的数据库中。不是我对数据做了什么特别的事情,而是我可以获得数据。拥有后,做任何你需要做的事情。
对于这些类型的任务,您很可能会在中间搞砸事情,因此您不想在流程中断时重新开始。由于偏爱 Mojolicious,我想我会将这些链接插入到 Minion 作业队列中,然后适当地处理该队列,以免网站运营商禁止我。
不仅如此,您还可能再次运行此程序以获取新案例。您不想重做已经完成的任何事情。
#!perl
use v5.12;
use Mojo::UserAgent;
use Mojo::Util qw(dumper trim);
my $url = 'http://media.ca7.uscourts.gov/cgi-bin/rssExec.pl?Time=month&FromMonth=01&FromDay=01&FromYear=1998&ToMonth=&ToDay=&ToYear=&Author=any&AuthorName=&Case=any&CaseY1=&CaseY2=&CaseN1=&CaseN2=&CaseN3=&CaseN4=&Submit=Submit&RssJudgeName=Sykes&OpsOnly=yes';
my $ua = Mojo::UserAgent->new;
my $results = $ua
->get( $url )
->result
->dom
->find( 'tr[bgcolor]' )
->map( sub {
my $row = $_;
my( $case_number, $caption, $case_type, $file, $author )
= map {
eval { trim($row->at( ":nth-child($_)" )->all_text) }
} qw( 1 2 3 4 6 );
my $link = eval { $row->at( "td:nth-child(5) a" )->attr('href') };
return {
case_number => $case_number,
caption => $caption,
case_type => $case_type,
file => $file,
author => $author,
link => $link,
}
} )
->to_array;
say dumper( $results );
输出如下:
[
{
"author" => "Flaum",
"caption" => "Paula McAllister v. \x{a0} Innovation Ventures, LLC",
"case_number" => "20-1779",
"case_type" => "civil",
"file" => "12/30/2020",
"link" => "/cgi-bin/rssExec.pl?Submit=Display&Path=Y2020/D12-30/C:20-1779:J:Flaum:aut:T:fnOp:N:2636910:S:0"
},
{
"author" => "PerCuriam",
"caption" => "USA v. \x{a0} Eduardo Ramirez",
"case_number" => "20-1006",
"case_type" => "criminal",
"file" => "12/29/2020",
"link" => "/cgi-bin/rssExec.pl?Submit=Display&Path=Y2020/D12-29/C:20-1006:J:PerCuriam:aut:T:fnOp:N:2636244:S:0"
},
{
"author" => "St__Eve",
"caption" => "USA v. \x{a0} Jermaine Stamps",
"case_number" => "20-1336",
"case_type" => "criminal",
"file" => "12/29/2020",
"link" => "/cgi-bin/rssExec.pl?Submit=Display&Path=Y2020/D12-29/C:20-1336:J:St__Eve:aut:T:fnOp:N:2635847:S:0"
},
...
]