在这文章里,我将展示如何进一步修改我们的电子邮址提取脚本,注入爬行能力,并收集尽可能最多的电子邮址。
诀窍很简单 - 我们不要爬行整个网站并检查每个网页。这样做会消耗大量的带宽和时间。我们只需要抓取网页有针对性的电子邮件列表,因此,只要我们知道总页数,然后循环从第一页到最后一页就可完成任务了!
首先,检查目标网站的分页。在这个例子中,它有页面1,2,3,...和“Last”页面按钮。按下此钮将带我们到最后一页,第169页。每个页面有10个电子邮件地址,所以从这个网站可以得到将近1690电子邮址。页面总数(目前为169)将来是可以改变的。如果我们想重用我们的电子邮件提取脚本,它必须能够自动检测总页数。
现在我们来看看这个分页的源文件。
我们提取电子邮址之前,我们需要解析最后一页的页码。这是 httpcurl.php代码。
<?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>~'); define('LASTPAGE', '~<li class="pager-last last"><a href="/negotiators\?page=(.*?)"~'); define('PARSE_CONTENT', TRUE); 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, $status = FALSE) { $this->request($url); if ($status === TRUE) { return $this->runParser($this->_body, $this->getStatus()); } } 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); } 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); } } } ?>
首先,我添加了两个定义:
define('LASTPAGE', '~<li class="pager-last last"><a href="/negotiators\?page=(.*?)"~'); define('PARSE_CONTENT', TRUE);
LASTPAGE从URL解析最后一页数。请注意,有一个"?"在URL中,所以我们需要"\?"对其进行转义。
PARSE_CONTENT告诉函数 get()是否要执行runParser()。 $status默认设置为“FALSE”,只执行函数request()。如果把PARSE_CONTENT传递给$status,那么函数get()将另外执行runParser(),在网页中提取电子邮址,姓名及联络电话号码列表。
public function get($url, $status = FALSE) { $this->request($url); if ($status === TRUE) { return $this->runParser($this->_body, $this->getStatus()); } }
test.php也有修改。
<?php include 'httpcurl.php'; $target = "http://《网站域名》/negotiators?page="; $startPage = $target . "1"; $scrapeContent = new Scraper; $firstPage = new HttpCurl(); $firstPage->get($startPage); if ($firstPage->getStatus() === 200) { $lastPage = $scrapeContent->matchPattern(LASTPAGE, $firstPage->getBody(), 1); } $pages = new HttpCurl($scrapeContent); for($i=1; $i <= $lastPage; $i++) { $targetPage = $target . $i; $pages->get($targetPage, PARSE_CONTENT); } ?>
首先,共有169页的房地产代理信息。每个页面的结构
<domain的目标website>/negotiators?page= 1,2,3,4, 至页169。因此,我们可以创建一个循环$target.$i。为了得到第一个页面,$startPage = $target . 1, 就是
<domain的目标website>/negotiators?page= 1。
我们实例化两个对象
$scrapeContent = new Scraper; $firstPage = new HttpCurl();
当我们读取第一页配合模式“LASTPAGE”,我们得到169号返回$lastpage。有了这个信息,我们可以创建循环.
for($i=1; $i <= $lastPage; $i++)
现在,我们实例化另一个对象$pages,循环每一个页面直到最后一页。我提取到1687个电子邮件地址及相关信息。现在是时候管理大量数据。
接下来,我们需要将这些信息存储到MySQL。我们可以从众多的网站收集高达几十万电子邮件地址,并将它们存储到MySQL。我们也可以存储CSV格式文件及导入电子邮件管理软件。然后发出海量邮件至我们的目标。这将在第4部分讨论。