【问题标题】:malformed url versus broken link in perlperl 中格式错误的 url 与损坏的链接
【发布时间】:2013-07-02 16:38:02
【问题描述】:

我希望区分 url 中的拼写错误和实际断开的链接。例如:

错字: www.google/com

链接断开: www.thislinkpointstonothing.org

我希望我的应用程序将第一个 URL 识别为格式错误,并指示第二个 URL 在查询时返回 404 未找到。我可以使用 perl 模块或正则表达式来区分吗?

我正在尝试区分由于拼写错误导致的错误链接,或者 - 如果链接遵循 RFC - 错误链接仅仅是因为页面不再存在。

【问题讨论】:

  • 如果 www.google/com 给你一个 404,而不是名称服务器错误等,我会担心你的代码/配置。
  • 可以添加 expr 来检查有效的 url /something.something.com/
  • 一个正则表达式怎么可能决定某个 URL 是昨天有效还是一个错字?如果可以,我能否判断该网址明天是否可以使用?
  • 我的意思是一个正则表达式,它可以告诉一个 url 不遵循 rfc
  • 这根本不是你的问题。

标签: perl url


【解决方案1】:

您在谈论两种不同类型的“查询”:DNS 查找和 HTTP 请求。 HTTP 请求使用 DNS 查找 - 但并非总是如此。例如,服务器可以位于本地网络上,您可以使用来自/etc/hosts 文件的 IP 地址和名称信息向其请求页面。链接名称可能并不总是包含主机名部分,因为它们可能是相对的(这通常是一种很好的做法,可以使网站能够轻松地移动到反向代理后面或主机名发生变化时。

考虑到这种区别,您的问题的要点 - 您是否可以检查链接的 URI 正确性与真正缺少页面 (404) 是合理的 - 但对 google/com 的 DNS 查询应该不会成功.您的应用程序是否被代理重定向到搜索页面?

下面是一个粗略的近似答案 - 这可能不会有太大用处,但你会明白的。对于perl 中更有用的方法,您可能想检查一些功能更强大的perl 框架(CatalystMojo)是否有执行此操作的方法。此外,如果您正在为您的前端 UI(即网页上的javascript)执行此操作,则可能会有更快或更简单的成熟方法。以下步骤似乎是您想要对每个链接执行的操作:

1 检查链接/URI 是否“正常”;如果不打印错误;如果是那么:

2 对链接/URI 的主机部分进行 DNS 查找;如果不打印错误;如果成功则:

3 尝试获取网页并打印任何错误,或者如果成功则说明

衡量“成功”很难自动化:是否应该将其严格定义为状态“200 OK”?也许您或其他成员可以添加该部分并找到一种优雅的方式来阅读“链接”(损坏或其他)。

这个脚本草率地使用了our 来存储东西,并且不会使用use strict 运行。请有人让它看起来更好,并且只使用 CORE:: modules :-)

use Regexp::Common qw/URI/;                                    
use Net::DNS;                       
use 5.10.0;                                                                 
use LWP::UserAgent; 

my $url = "http://www.google.com/adsfdsa" ;  
my $lookup = Net::DNS::Resolver->new;                                       
my $ua = LWP::UserAgent->new;                                               

### Step 0. regexp the URI  ##                                              

if ($url =~ /$RE{URI}{HTTP}{-keep}/){                                       
  say "$url is a URI ";                                                 
  our $hostpart = $3;  # stash the host part as per man page                
  our $filepart = $5;  # stash the path                                     
}                                                                           

### Step 1.  do a DNS look up and if it succeeds then or else ... etc. ###      

if ($lookup->query($hostpart))  { say "$hostpart is a valid host" }         
else { say " but $hostpart is an invalid host" }                            

###  Step 2. fetch the page and check the return code ###                   

my $request = HTTP::Request->new(GET => $url);                              
my $response = $ua->request($request);                                      

if ($response->is_success || $response->is_redirect ) {                     
    print $request->content;                                                
}                                                                           
else {                                                                      
  say "but $filepart is an invalid path";                                   
}  

输出:

http://www.google.com/adsfdsa is a URI
www.google.com is a valid host
but /adsfdsa is an invalid path

您可以进行类似上述的操作(但更短、更优雅、更高效!)从您的输入中读取并将适当的消息返回给您的用户,即从发生错误的地方:即在步骤 0.、1 或 2 .)。请注意,可能有更快、更简单的方法可以做到这一点,但是像 Regexp::CommonLWP 这样的模块已经过很好的练习和测试。

【讨论】:

    猜你喜欢
    • 2016-05-02
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 2016-05-26
    相关资源
    最近更新 更多