Maison  >  Article  >  développement back-end  >  Techniques de concurrence et multithreading pour les robots d'exploration PHP

Techniques de concurrence et multithreading pour les robots d'exploration PHP

PHPz
PHPzoriginal
2023-08-08 14:31:451212parcourir

Techniques de concurrence et multithreading pour les robots dexploration PHP

Compétences de traitement simultané et multithread des robots d'exploration PHP

Introduction :
Avec le développement rapide d'Internet, une grande quantité d'informations de données est stockée sur divers sites Web, et l'obtention de ces données est devenue une exigence dans de nombreuses entreprises scénarios. En tant qu'outil permettant d'obtenir automatiquement des informations sur le réseau, les robots d'exploration sont largement utilisés dans la collecte de données, les moteurs de recherche, l'analyse de l'opinion publique et d'autres domaines. Cet article présentera une technique de traitement simultané et multithread pour une classe de robot d'exploration basée sur PHP et illustrera sa mise en œuvre à travers des exemples de code.

1. La structure de base de la classe reptile
Avant d'implémenter la concurrence et le traitement multi-thread de la classe reptile, examinons d'abord la structure d'une classe reptile de base.

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;
    }
}

Dans le code ci-dessus, nous définissons d'abord une classe Crawler et transmettons une URL de départ via le constructeur. Dans la méthode crawl(), nous obtenons d’abord le contenu de la page de démarrage, puis analysons le contenu de la page et extrayons les informations requises. Ensuite, nous pouvons traiter les informations obtenues, par exemple les stocker dans une base de données. Enfin, nous récupérons les liens dans la page et explorons de manière récursive d’autres pages.

2. Traitement simultané
Normalement, les robots d'exploration doivent traiter un grand nombre d'URL et les opérations d'E/S des requêtes réseau prennent beaucoup de temps. Si nous utilisons l'exécution séquentielle, demander la suivante une fois qu'une requête est terminée réduira considérablement notre efficacité d'exploration. Afin d'améliorer les capacités de traitement simultané, nous pouvons utiliser l'extension multi-processus de PHP pour y parvenir.

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请求,获取页面内容
        // ...
        // 解析页面内容,获取需要的信息
        // ...
        // 处理获取到的信息,进行逻辑处理或存储
        // ...
    }
}

Dans le code ci-dessus, nous définissons d'abord une classe ConcurrentCrawler et transmettons un ensemble d'URL qui doivent être explorées via le constructeur. Dans la méthode crawl(), nous utilisons la méthode multi-processus pour le traitement simultané. En utilisant la fonction pcntl_fork(), une partie de l'URL est traitée dans chaque processus enfant, tandis que le processus parent est responsable de la gestion du processus enfant. Enfin, attendez la fin de tous les processus enfants via la fonction pcntl_wait().

3. Traitement multithread
En plus d'utiliser plusieurs processus pour le traitement simultané, nous pouvons également utiliser l'extension Thread de PHP pour implémenter un traitement multithread.

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();
        }
    }
}

Dans le code ci-dessus, nous définissons d'abord une classe MultithreadCrawler, qui hérite de la classe Thread, et réécrit la méthode run() comme logique principale du thread. Dans la classe Executor, nous créons plusieurs threads via une boucle et les démarrons pour leur exécution. Enfin, attendez la fin de tous les threads via la méthode join().

Conclusion : 
Grâce à l'introduction des techniques de traitement simultané et multi-thread des robots d'exploration PHP, nous pouvons constater que le traitement simultané et le traitement multi-thread peuvent considérablement améliorer l'efficacité de l'exploration du robot. Toutefois, dans le processus de développement proprement dit, nous devons choisir la méthode de traitement appropriée en fonction de la situation spécifique. Dans le même temps, afin d'assurer la sécurité des multi-threads ou multi-processus, nous devons également effectuer des opérations de synchronisation appropriées pendant le traitement.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn