PHP Email地址提取脚本cURL和正则表达式 (2)

HP Email地址提取脚本cURL和正则表达式

在本文里,我们需要稍微修改之前的PHP Email地址提取脚本。

首先,我们看回该网页的源文件,可以看到有重复块代理联系人的姓名,电子邮件和电话号码。每页有10块。

我们的策略是使用脚本“切出”每一块资料,然后存储到数组,再提取每块资料里的姓名,电子邮件和电话号码。

正如您看到的,每块以标签<div class="negotiators-wrapper">开头及以</ div></ div>结束。请注意,在这个例子中的回车和新换行分隔</ div>标记。

网页的源文件

这个例子的代码:

<?php
define('TARGET_BLOCK','~<div class="negotiators-wrapper">(.*?)</div>(\r\n)</div>~s');
define('NAME', '~<div class="negotiators-name"><a href="/negotiator/(.*?)">(.*?)</a></div>~');
define('EMAIL', '~<div class="negotiators-email">(.*?)</div>~');
define('PHONE', '~<div class="negotiators-phone">(.*?)</div>~');
 
interface HttpScraper
{
    public function parse($body, $head);
}
  
class Scraper implements HttpScraper
{
    public function parse($body, $head) {
       if ($head == 200) {    
        $p = preg_match_all(TARGET_BLOCK, $body, $blocks);         
            if ($p) {
                foreach($blocks[0] as $block) {
                    $agent[name] = $this->matchPattern(NAME, $block, 2);
                    $agent[email] = $this->matchPattern(EMAIL, $block, 1);
                    $agent[phone] = $this->matchPattern(PHONE, $block, 1);
                    echo "<pre>"; print_r($agent); echo "</pre>";
               }
            }
        }
    }
     
    public function matchPattern($pattern, $content, $pos) {
        if (preg_match($pattern, $content, $match)) {
            return $match[$pos];
        }  
    }
}
  
class HttpCurl {
    protected $_cookie, $_parser, $_timeout;
    private $_ch, $_info, $_body, $_error;
      
    public function __construct($p = null) {
        if (!function_exists('curl_init')) {
            throw new Exception('cURL not enabled!');
        } 
        $this->setParser($p);
    }
  
    public function get($url) {
        return $this->request($url);
    }
  
    protected function request($url) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 5);   
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_URL, $url);
        $this->_body = curl_exec($ch);
        $this->_info  = curl_getinfo($ch);
        $this->_error = curl_error($ch);
        curl_close($ch);
  
        $this->runParser($this->_body, $this->getStatus());              
    }
  
    public function getStatus() {
        return $this->_info[http_code];
    }
      
    public function getHeader() {
        return $this->_info;
    }
  
    public function getBody() {
        return $this->_body;
    }
      
    public function __destruct() {
    } 
      
    public function setParser($p)   {
        if ($p === null || $p instanceof HttpScraper || is_callable($p))  
            $this->_parser = $p;
    }
  
    public function runParser($content, $header)    {
        if ($this->_parser !== null)
        {
            if ($this->_parser instanceof HttpScraper)
                $this->_parser->parse($content, $header);
            else
                call_user_func($this->_parser, $content, $header);
        }
    } 
}
  
?>

 

如何操作:

首先,我定义TARGET_BLOCK为前面所讨论重复块。

define('TARGET_BLOCK','~<div class="negotiators-wrapper">(.*?)</div>(\r\n)</div>~s');

 当运行在Window7的XAMPP,回车和新行\ r \ n顺利匹配。此外,正则表达式“S”修饰符用于模式匹配多线代码。

要提取姓名,我定义 NAME为

define('NAME', '~<div class="negotiators-name"><a href="/negotiator/(.*?)">(.*?)</a></div>~');

 需要注意的是前面有个一个URL“>(姓名)</ a></ div>。网址在每块是不同的。preg_match()函数将匹配两个组数据,首先是URL部分的信息,和第二组的目标姓名。在这种情况下,我们将忽略的URL信息。

获得电子邮件和电话号码会比较直接。

define('EMAIL', '~<div class="negotiators-email">(.*?)</div>~');
define('PHONE', '~<div class="negotiators-phone">(.*?)</div>~');

 Scraper类只是有一些小改变:

class Scraper implements HttpScraper
{
    public function parse($body, $head) {
       if ($head == 200) {    
        $p = preg_match_all(TARGET_BLOCK, $body, $blocks);         
            if ($p) {
                foreach($blocks[0] as $block) {
                    $agent[name] = $this->matchPattern(NAME, $block, 2);
                    $agent[email] = $this->matchPattern(EMAIL, $block, 1);
                    $agent[phone] = $this->matchPattern(PHONE, $block, 1);
                    echo "<pre>"; print_r($agent); echo "</pre>";
               }
            }
        }
    }
     
    public function matchPattern($pattern, $content, $pos) {
        if (preg_match($pattern, $content, $match)) {
            return $match[$pos];
        }  
    }
}

 

首先,函数parse()匹配及把资料块复制到阵列,然后我们从中提取姓名,电子邮件和电话号码。其余的代码保持不变。

在本文中,我们运行test.php,并打印出结果:

提取姓名,电子邮件和电话号码

行了!

现在可以写给您的目标一个更加个性化的电子邮件。您可以使用电子邮件管理软件等ListMailPro或任何软件并发送大量电子邮件。

到目前为止,我们的脚本只能够从一个网页提取电子邮件。要提取大量电子邮件,我们的脚本需要能够抓取整个网站的信息。这将在下一章讨论。

 

最后修改于 星期四, 03 11月 2016 06:31
给本项目评分
(0 得票数)
返回顶部