如何在使用PHP进行Web抓取时跳过包含文件扩展名的链接

时间:2012-01-01 16:46:11

标签: php mysql web-scraping web-crawler

这是一个验证.edu TLD并检查url是否指向.pdf文档或.doc文档的函数。

public function validateEduDomain($url) {
    if( preg_match('/^https?:\/\/[A-Za-z]+[A-Za-z0-9\.-]+\.edu/i', $url) && !preg_match('/\.(pdf)|(doc)$/i', $url) )  {
        return TRUE;
    }
    return FALSE;

现在我遇到指向jpg,rtf和其他人的链接,simple_html_dom尝试解析并返回其内容。我想通过跳过所有这些链接来避免这种情况发生。问题是该列表并非详尽无遗,我希望代码跳过所有这些链接。我该怎么做?

2 个答案:

答案 0 :(得分:4)

在许多情况下,通过猜测它背后的内容总是会失败来过滤网址。假设您使用curl进行下载,您应该检查响应文档类型标题是否属于可接受的标题:

<?php

require "simple_html_dom.php";

$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //default is to output it

$urls = array(
  "google.com", 
  "https://www.google.com/logos/2012/newyearsday-2012-hp.jpg", 
  "http://cran.r-project.org/doc/manuals/R-intro.pdf",
);
$acceptable_types = array("text/html", "application/xhtml+xml");

foreach ($urls as $url) {
  curl_setopt($curl, CURLOPT_URL, $url);
  $contents = curl_exec($curl);

  //we need to handle content-types like "text/html; charset=utf-8"
  list($response_type) = explode(";", curl_getinfo($curl, CURLINFO_CONTENT_TYPE));

  if (in_array($response_type, $acceptable_types)) {
    echo "accepting {$url}\n";
    // create a simple_html_dom object from string
    $obj = str_get_html($contents);
  } else {
    echo "rejecting {$url} ({$response_type})\n";
  }
}

运行上述结果:

accepting google.com
rejecting https://www.google.com/logos/2012/newyearsday-2012-hp.jpg (image/jpeg)
rejecting http://cran.r-project.org/doc/manuals/R-intro.pdf (application/pdf)

答案 1 :(得分:0)

将最后一个正则表达式更新为:

!preg_match('/\.(pdf)|(doc)|(jpg)|(rtf)$/i', $url) )

将过滤掉jpgs和rtf文件。

您必须在上面的正则表达式中添加扩展名以省略它们。

<强>更新

我认为不可能阻止所有类型的扩展,我个人也不建议它也用于刮擦使用。您必须跳过一些扩展才能继续抓取。为什么不把你的正则表达式过滤器更改为你想接受的那些:

preg_match('/\.(html)|(html)|(php)|(aspx)$/i', $url) )