Kemahiran pemprosesan selaras dan berbilang benang perangkak PHP
Pengenalan:
Dengan perkembangan pesat Internet, sejumlah besar maklumat data disimpan di pelbagai tapak web, dan mendapatkan data ini telah menjadi keperluan dalam banyak perniagaan senario. Sebagai alat untuk mendapatkan maklumat rangkaian secara automatik, perangkak digunakan secara meluas dalam pengumpulan data, enjin carian, analisis pendapat umum dan bidang lain. Artikel ini akan memperkenalkan teknik pemprosesan serentak dan berbilang benang untuk kelas perangkak berasaskan PHP, dan menggambarkan pelaksanaannya melalui contoh kod.
1. Struktur asas kelas reptilia
Sebelum melaksanakan pemprosesan serentak dan berbilang benang bagi kelas reptilia, mari kita lihat dahulu struktur kelas reptilia asas.
class Crawler { private $startUrl; public function __construct($startUrl) { $this->startUrl = $startUrl; } public function crawl() { // 获取初始页面的内容 $content = $this->getContent($this->startUrl); // 解析页面内容,获取需要的信息 $data = $this->parseContent($content); // 处理获取到的信息,进行业务逻辑处理或存储 $this->processData($data); // 获取页面中的链接,并递归抓取 $urls = $this->getUrls($content); foreach ($urls as $url) { $content = $this->getContent($url); $data = $this->parseContent($content); $this->processData($data); } } private function getContent($url) { // 发起HTTP请求,获取页面内容 // ... return $content; } private function parseContent($content) { // 解析页面内容,提取需要的信息 // ... return $data; } private function processData($data) { // 处理获取到的信息,进行逻辑处理或存储 // ... } private function getUrls($content) { // 获取页面中的链接 // ... return $urls; } }
Dalam kod di atas, kami mula-mula mentakrifkan kelas Crawler dan menghantar URL permulaan melalui pembina. Dalam kaedah crawl(), kami mula-mula mendapatkan kandungan halaman permulaan, kemudian menghuraikan kandungan halaman dan mengekstrak maklumat yang diperlukan. Selepas itu, kita boleh memproses maklumat yang diperolehi, seperti menyimpannya dalam pangkalan data. Akhir sekali, kami mendapat pautan dalam halaman dan merangkak halaman lain secara rekursif.
2. Pemprosesan serentak
Biasanya, perangkak perlu memproses sejumlah besar URL, dan operasi IO bagi permintaan rangkaian sangat memakan masa. Jika kami menggunakan pelaksanaan berurutan, meminta yang seterusnya selepas satu permintaan selesai akan mengurangkan kecekapan merangkak kami. Untuk meningkatkan keupayaan pemprosesan serentak, kami boleh menggunakan sambungan berbilang proses PHP untuk mencapai matlamat ini.
class ConcurrentCrawler { private $urls; public function __construct($urls) { $this->urls = $urls; } public function crawl() { $workers = []; $urlsNum = count($this->urls); $maxWorkersNum = 10; // 最大进程数 for ($i = 0; $i < $maxWorkersNum; $i++) { $pid = pcntl_fork(); if ($pid == -1) { die('fork failed'); } else if ($pid == 0) { for ($j = $i; $j < $urlsNum; $j += $maxWorkersNum) { $this->processUrl($this->urls[$j]); } exit(); } else { $workers[$pid] = true; } } while (count($workers)) { $pid = pcntl_wait($status, WUNTRACED); if ($status == 0) { unset($workers[$pid]); } else { $workers[$pid] = false; } } } private function processUrl($url) { // 发起HTTP请求,获取页面内容 // ... // 解析页面内容,获取需要的信息 // ... // 处理获取到的信息,进行逻辑处理或存储 // ... } }
Dalam kod di atas, kami mula-mula mentakrifkan kelas ConcurrentCrawler dan menghantar satu set URL yang perlu dirangkak melalui pembina. Dalam kaedah crawl(), kami menggunakan kaedah berbilang proses untuk pemprosesan serentak. Dengan menggunakan fungsi pcntl_fork(), sebahagian daripada URL diproses dalam setiap proses anak, manakala proses induk bertanggungjawab untuk mengurus proses anak. Akhir sekali, tunggu penghujung semua proses anak melalui fungsi pcntl_wait().
3. Pemprosesan berbilang benang
Selain menggunakan pelbagai proses untuk pemprosesan serentak, kami juga boleh menggunakan sambungan Benang PHP untuk melaksanakan pemprosesan berbilang benang.
class MultithreadCrawler extends Thread { private $url; public function __construct($url) { $this->url = $url; } public function run() { // 发起HTTP请求,获取页面内容 // ... // 解析页面内容,获取需要的信息 // ... // 处理获取到的信息,进行逻辑处理或存储 // ... } } class Executor { private $urls; public function __construct($urls) { $this->urls = $urls; } public function execute() { $threads = []; foreach ($this->urls as $url) { $thread = new MultithreadCrawler($url); $thread->start(); $threads[] = $thread; } foreach ($threads as $thread) { $thread->join(); } } }
Dalam kod di atas, kami mula-mula mentakrifkan kelas MultithreadCrawler, yang mewarisi daripada kelas Thread, dan menulis semula kaedah run() sebagai logik utama utas. Dalam kelas Executor, kami mencipta berbilang benang melalui gelung dan memulakannya untuk pelaksanaan. Akhir sekali, tunggu penghujung semua utas melalui kaedah join().
Kesimpulan:
Melalui pengenalan teknik pemprosesan konkurensi dan berbilang benang perangkak PHP, kami dapati bahawa kedua-dua pemprosesan konkurensi dan pemprosesan berbilang benang boleh meningkatkan kecekapan rangkak perangkak. Walau bagaimanapun, dalam proses pembangunan sebenar, kita perlu memilih kaedah pemprosesan yang sesuai mengikut situasi tertentu. Pada masa yang sama, untuk memastikan keselamatan berbilang benang atau berbilang proses, kami juga perlu melakukan operasi penyegerakan yang sesuai semasa pemprosesan.
Atas ialah kandungan terperinci Teknik concurrency dan multi-threading untuk perangkak PHP. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!