iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 30
1
Modern Web

寫給PHP開發者的30堂網路爬蟲開發系列 第 30

Day 30:案例整合 2-2 寄信整合 part 2

前言

在昨天,我們利用了MailGun的寄信API協助我們發送最新學校消息,這是一種利用API請求的方法去寄信的方式。

在本文章中,要利用MailGun提供的最原本的SMTP方式,將學校最新消息利用此方法寄送信件。

環境啟動

首先,先將爬蟲的Docker環境重新啟動,啟動方式如下指令:

docker run -it --name=php_crawler -d php_crawler bash

接著,利用下面的指令進入正在運行Docker容器環境中:

docker exec -it php_crawler bash

接著,運行composer.phar安裝PHPMailer套件,其指令如下:

root@6f69c5553c00:~# php composer.phar require phpmailer/phpmailer

安裝好之後,接著使用偏好的程式編輯器將lab1-1.php打開,並改成下面程式碼:

<?php

define('MAILGUN_URL', 'https://api.mailgun.net/v3/sandbox5099c0f44ddb4ce0883b7ed9d2a87499.mailgun.org');
define('MAILGUN_KEY', 'key-MAILGUN_KEY');

require_once __DIR__ . '/vendor/autoload.php';

use GuzzleHttp\Client;
use Symfony\Component\DomCrawler\Crawler;

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

$latestNews = 'https://www.nttu.edu.tw/p/503-1000-1009.php';
$client = new Client();
$response = $client->request('GET', $latestNews);

$latestNewsString = (string)$response->getBody();

$titles = [];
$descriptions = [];
$pubDates = [];
$links = [];
$authors = [];

$crawler = new Crawler($latestNewsString);

$crawler
    ->filter('title')
    ->reduce(function (Crawler $node, $i) {
        global $titles;
        $titles[] = $node->text();
    });

$crawler
    ->filter('description')
    ->reduce(function (Crawler $node, $i) {
        global $descriptions;
        $descriptions[] = str_replace([" ", "\n", "\r", "\t"], "", strip_tags($node->text()));
    });

$crawler
    ->filter('pubDate')
    ->reduce(function (Crawler $node, $i) {
        global $pubDates;
        $pubDates[] = $node->text();
    });

$crawler
    ->filter('link')
    ->reduce(function (Crawler $node, $i) {
        global $links;
        $links[] = $node->text();
    });

$crawler
    ->filter('author')
    ->reduce(function (Crawler $node, $i) {
        global $authors;
        $authors[] = $node->text();
    });

// var_dump($descriptions);
// var_dump($pubDates);
// var_dump($links);
// var_dump($authors);
// var_dump($titles);

$text = implode(',', $descriptions) . "\n" . implode(',', $pubDates) . "\n" . implode(',', $links) . "\n";
$text .= implode(',', $authors) . "\n" . implode(',', $titles) . "\n";

$result = sendMailByMailGunSmtp('test', $text);

function sendMailByMailGunSmtp($subject, $body) {
    $mail = new PHPMailer(true);
    $mail->CharSet = 'UTF-8';

    try {
        $mail->SMTPDebug = SMTP::DEBUG_SERVER;
        $mail->isSMTP();
        $mail->Host       = 'smtp.mailgun.org';
        $mail->SMTPAuth   = true;
        $mail->Username   = 'user@domain.name';
        $mail->Password   = 'SMTP_AUTH_PASSWORD';
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port       = 587;

        $mail->setFrom('admin@domain.name', 'Mailer');
        $mail->addAddress('to_address@domain.com');

        $mail->isHTML(false);
        $mail->Subject = $subject;
        $mail->Body    = $body;
        $mail->AltBody = $body;

        $mail->send();

        echo 'Message has been sent';
    } catch (Exception $e) {
        echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
    }
}

function sendMailByMailGun($to, $toName, $mailFromName, $mailFrom, $subject, $html, $text, $tag, $replyTo) {
    $array_data = [
		'from'=> $mailFromName .'<'.$mailFrom.'>',
		'to'=>$toName.'<'.$to.'>',
		'subject'=>$subject,
		'html'=>$html,
		'text'=>$text,
		'o:tracking'=>'yes',
		'o:tracking-clicks'=>'yes',
		'o:tracking-opens'=>'yes',
		'o:tag'=>$tag,
		'h:Reply-To'=>$replyTo
    ];

    $session = curl_init(MAILGUN_URL.'/messages');
    curl_setopt($session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
  	curl_setopt($session, CURLOPT_USERPWD, 'api:'.MAILGUN_KEY);
    curl_setopt($session, CURLOPT_POST, true);
    curl_setopt($session, CURLOPT_POSTFIELDS, $array_data);
    curl_setopt($session, CURLOPT_HEADER, false);
    curl_setopt($session, CURLOPT_ENCODING, 'UTF-8');
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($session, CURLOPT_SSL_VERIFYPEER, false);
    $response = curl_exec($session);
    curl_close($session);

    $results = json_decode($response, true);

    return $results;
}

接著,將之前開發的lab1-1.php複製到運行的Docker容器爬蟲開發環境中,用如下指令:

docker cp lab1-1.php  php_crawler:/root/

接著,執行lab1-1.php程式,其使用指令如下:

docker exec php_crawler php lab1-1.php 

接著,看到下面類似的訊息,就表示發送信件成功了:

.......
5=A0=B1=E5=90=8D=E5=94=B7^^,=E3=80=
2019-10-15 15:41:45	CLIENT -> SERVER: =90=E6=95=99=E5=8B=99=E8=99=95=E3=80=91=E5=A4=A7=E4=B8=80=E6=96=B0=E7=94=
2019-10-15 15:41:45	CLIENT -> SERVER: =9F=E3=80=8C=E9=81=8B=E5=8B=95=E3=80=81=E7=BE=8E=E8=A1=93=E3=80=81=E9=9F=
2019-10-15 15:41:45	CLIENT -> SERVER: =B3=E6=A8=82=E3=80=8D=E7=B8=BE=E5=84=AA=E7=8D=8E=E5=AD=B8=E9=87=91=E7=94=
2019-10-15 15:41:45	CLIENT -> SERVER: =B3=E8=AB=8B=E5=85=AC=E5=91=8A,=E3=80=90=E7=A7=98=E6=9B=B8=E5=AE=A4=
2019-10-15 15:41:45	CLIENT -> SERVER: =E3=80=91=E6=9D=B1=E5=A4=A7=E7=B0=A1=E8=A8=8A-13=E8=99=9F=E5=88=8A(20190903=
2019-10-15 15:41:45	CLIENT -> SERVER: )=0A
2019-10-15 15:41:45	CLIENT -> SERVER:
2019-10-15 15:41:45	CLIENT -> SERVER: --b1_bfAQnYwle5u40h6SdPuNskz9EoDJCcpjUCJayxDX6cg--
2019-10-15 15:41:45	CLIENT -> SERVER:
2019-10-15 15:41:45	CLIENT -> SERVER: .
2019-10-15 15:41:46	SERVER -> CLIENT: 250 Great success
2019-10-15 15:41:46	CLIENT -> SERVER: QUIT
2019-10-15 15:41:46	SERVER -> CLIENT: 221 See you later. Yours truly, Mailgun
Message has been sent⏎

接著,檢查信箱,就會發現一封類似下面的訊息:

https://ithelp.ithome.com.tw/upload/images/20191015/20103975f7NoWxj9qT.png

到這裡,利用SMTP方式發信案例整合就完成了,上述的方法表示如下:

  • 先建立一個新的函式叫做sendMailByMailGunSmtp
  • 接著上述函式參數有:$subject, $body,分別是主旨與信件的內容
  • 接著,分別把下面的參數替換成相對應的SMTP相關資訊:
$mail->Host // 指的是 SMTP 主機
$mail->Username // SMTP 使用者名稱
$mail->Password  // SMTP 驗證密碼
$mail->setFrom('admin@domain.com', 'Mailer'); // 寄件者信箱與名稱
$mail->addAddress('to_address@domain.com'); // 這裡改成收件者信箱

結論

到這裡,30天給PHP開發者的爬蟲開發就結束了,雖然涵蓋內容沒有到很多,不過我認為是很實用的,不論是從每個案例爬蟲與解析網頁內容的思路與實做內容。

以及到後面的案例整合,都是有可以拿來直接使用的地方。

希望各位PHP開發者,在日後開發爬蟲有一個概念,在以後爬蟲實做上有好的經驗與起手式!


上一篇
Day 29:案例整合 2-1 發信API寄送整合
系列文
寫給PHP開發者的30堂網路爬蟲開發30

1 則留言

0
阿展展展
iT邦好手 1 級 ‧ 2020-02-29 06:50:13

恭喜完賽 恭喜獲得佳作!

我要留言

立即登入留言