PHP爬蟲類的并發與多線程處理技巧

php爬蟲類的并發與多線程處理技巧

PHP爬蟲類的并發與多線程處理技巧

引言:
隨著互聯網的快速發展,大量的數據信息存儲在各種網站上,獲取這些數據已經成為很多業務場景下的需求。而爬蟲作為一種自動化獲取網絡信息的工具,被廣泛應用于數據采集、搜索引擎、輿情分析等領域。本文將介紹一種基于PHP的爬蟲類的并發與多線程處理技巧,并通過代碼示例來說明其實現方式。

一、爬蟲類的基本結構
在實現爬蟲類的并發與多線程處理前,我們先來看一下一個基本的爬蟲類的結構。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

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;

????}

}

上述代碼中,我們首先定義一個Crawler類,通過構造函數傳入一個起始URL。在crawl()方法中,我們首先獲取起始頁面的內容,然后解析頁面內容,提取需要的信息。之后,我們可以對獲取到的信息進行處理,比如存儲到數據庫中。最后,我們獲取頁面中的鏈接,并遞歸抓取其他頁面。

二、并發處理
通常情況下,爬蟲需要處理大量的URL,而網絡請求的IO操作非常耗時。如果我們采用順序執行的方式,一個請求完畢后再請求下一個,會極大地降低我們的抓取效率。為了提高并發處理能力,我們可以采用PHP的多進程擴展來實現。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

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請求,獲取頁面內容

????????// ...

????????// 解析頁面內容,獲取需要的信息

????????// ...

????????// 處理獲取到的信息,進行邏輯處理或存儲

????????// ...

????}

}

上述代碼中,我們首先定義了一個ConcurrentCrawler類,通過構造函數傳入一組需要抓取的URL。在crawl()方法中,我們使用了多進程的方式來進行并發處理。通過使用pcntl_fork()函數,在每個子進程中處理一部分URL,而父進程負責管理子進程。最后,通過pcntl_wait()函數等待所有子進程的結束。

三、多線程處理
除了使用多進程進行并發處理,我們還可以利用PHP的Thread擴展實現多線程處理。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

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

????????}

????}

}

上述代碼中,我們首先定義了一個MultithreadCrawler類,繼承自Thread類,并重寫了run()方法作為線程的主體邏輯。在Executor類中,我們通過循環創建多個線程,并啟動它們執行。最后,通過join()方法等待所有線程的結束。

結語:
通過對PHP爬蟲類的并發與多線程處理技巧的介紹,我們可以發現并發處理和多線程處理都能夠大大提高爬蟲的抓取效率。不過,在實際開發過程中,我們需要根據具體的情況選擇合適的處理方式。同時,為了保證多線程或多進程的安全性,我們還需要在處理過程中進行適當的同步操作。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/37380.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/37380.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/37380.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于組織赴俄羅斯(莫斯科)第 28 屆國際汽車零部件、汽車維修設備和商品展覽會商務考察的通知

關于組織赴俄羅斯&#xff08;莫斯科&#xff09; 第 28 屆國際汽車零部件、汽車維修設備和商品展覽會商務考察的通知 展會名稱&#xff1a;俄羅斯&#xff08;莫斯科&#xff09;第 28 屆國際汽車零部件、汽車零部件、汽車維修設備和商品展覽會 時間&#xff1a;2024 年 8 月…

Python | Leetcode Python題解之第204題計數質數

題目&#xff1a; 題解&#xff1a; MX5000000 is_prime [1] * MX is_prime[0]is_prime[1]0 for i in range(2, MX):if is_prime[i]:for j in range(i * i, MX, i):#循環每次增加iis_prime[j] 0 class Solution:def countPrimes(self, n: int) -> int:return sum(is_prim…

【MongoDB】分布式數據庫入門級學習

SueWakeup 個人主頁&#xff1a;SueWakeup 系列專欄&#xff1a;為祖國的科技進步添磚Java 個性簽名&#xff1a;保留赤子之心也許是種幸運吧 本文封面由 凱楠&#x1f4f8;友情提供 凱楠&#x1f4f8; - 不夜長安 目錄 MongoDB 相關 數據庫排行榜單 MongoDB 中文官網 菜鳥…

如何把mkv轉成mp4?介紹一下將mkv轉成MP4的幾種方法

如何把mkv轉成mp4&#xff1f;如果你有一個MKV格式的視頻文件&#xff0c;但是需要將其轉換為MP4格式以便更廣泛地在各種設備和平臺上播放和共享&#xff0c;你可以通過進行簡單的文件格式轉換來實現。轉換MKV到MP4格式可以提供更好的兼容性&#xff0c;并確保你的視頻文件能夠…

在預訓練語言模型主流架構

文章目錄 編碼器-解碼器架構因果解碼器架構前綴解碼器架構在預訓練語言模型時代,自然語言處理領域廣泛采用了預訓練 + 微調的范式,并誕生了以 BERT 為代表的編碼器(Encoder-only)架構、以 GPT 為代表的解碼器(Decoder-only)架構和以 T5 為代表的編碼器-解碼器(Encoder-d…

華為OD機試C卷(100分)-執行任務賺積分(c語言)

題目描述 現有N個任務需要處理&#xff0c;同一時間只能處理一個任務&#xff0c;處理每個任務所需要的時間固定為1。 每個任務都有最晚處理時間限制和積分值&#xff0c;在最晚處理時間點之前處理完成任務才可獲得對應的積分獎勵。 可用于處理任務的時間有限&#xff0c;請問…

AI學習指南機器學習篇-隨機森林超參數選擇與調優

AI學習指南機器學習篇-隨機森林超參數選擇與調優 隨機森林是一種強大的機器學習算法&#xff0c;它能夠處理復雜的數據集&#xff0c;并且對于大部分實際問題都表現出色。然而&#xff0c;要充分發揮隨機森林的性能&#xff0c;需要對其超參數進行合理選擇和調優。本文將介紹隨…

React:tabs或標簽頁自定義右擊菜單內容,支持內嵌iframe關閉菜單方案

React&#xff1a;tabs或標簽頁自定義右擊菜單內容&#xff0c;支持內嵌iframe關閉菜單方案 不管是react、vue還是原生js&#xff0c;原理是一樣的。 注意如果內嵌iframe情況下&#xff0c;iframe無法使用事件監聽&#xff0c;但是可以使用iframe的任何點擊行為都會往父級wind…

入門Java爬蟲:認識其基本概念和應用方法

Java爬蟲初探&#xff1a;了解它的基本概念與用途&#xff0c;需要具體代碼示例 隨著互聯網的快速發展&#xff0c;獲取并處理大量的數據成為企業和個人不可或缺的一項任務。而爬蟲&#xff08;Web Scraping&#xff09;作為一種自動化的數據獲取方法&#xff0c;不僅能夠快速…

Pegasus平臺Pytorch源碼編譯

和Drive PX2的編譯沒有什么區別 源碼編譯步驟 注意&#xff1a;當完全按照以下步驟進行編譯時&#xff0c;如果出現錯誤&#xff0c;注意檢查CUDA版本、對應的庫是否存在 # Download PyTorch sources git clone --recursive --branch <version> http://github.com/pyt…

vtk渲染過程

vtk渲染 VTK的渲染過程主要包括創建渲染器、添加演員到渲染器、創建渲染窗口、創建交互器、將渲染器添加到渲染窗口中、將交互器與渲染窗口關聯、啟動交互器循環等步驟。12 創建渲染器(Renderer): 首先&#xff0c;需要創建一個或多個渲染器。渲染器是VTK中的一個重要組件&am…

在Ubuntu 16.04上安裝和配置Elasticsearch的方法

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站。 簡介 Elasticsearch 是一個用于實時分布式搜索和數據分析的平臺。它因易用性、強大功能和可擴展性而備受歡迎。 Elasticsearch 支持 R…

vue2(vue-cli3x[vue.config.js])使用cesium新版(1.117.0)配置過程

看來很多解決方法都沒有辦法&#xff0c;最后終于。嗚嗚嗚嗚 這里我用的是vue-cli去搭建的項目的vue2 項目&#xff0c;其實不建議用vue2搭配cesium。因為目前cesium停止了對vue2的版本更新&#xff0c;現在默認安裝都是vue3版本&#xff0c;因此需要控制版本&#xff0c;否則…

Kylin支持哪些數據源,它們之間有什么區別

Apache Kylin支持多種數據源&#xff0c;這些數據源為Kylin提供了從不同類型和存儲方式的數據中獲取和處理數據的能力。以下是Kylin支持的主要數據源及其之間的區別&#xff1a; Apache Hadoop HDFS&#xff1a; 描述&#xff1a;HDFS是Hadoop生態系統中用于存儲大數據的文件系…

Node.js簡介

一&#xff1a;Node.js簡介 Node.js是一個跨平臺的JavaScript運行環境&#xff0c;使開發者可以搭建服務器端的JavaScript應用程序 作用&#xff1a;使用Node.js編寫服務器端程序 編寫數據接口&#xff0c;提供網頁資源瀏覽功能有利于前端工程化&#xff0c;可以集成各種開發…

鴻蒙系統的前世今生

2019年8月9日&#xff0c;華為在開發者大會上發布EMUI 10的同時宣告了HarmonyOS 1.0的誕生。鴻蒙誕生的背景是&#xff0c;美限制華為與谷歌以及其他美國科技公司開展業務。 前華為開發者大會上&#xff0c;HarmonyOS NEXT&#xff08;原生鴻蒙&#xff09;正式公布&#xff0c…

【力扣高頻題】011. 盛最多水的容器

前面的算法文章&#xff0c;更新了許多 專題系列 。包括&#xff1a;滑動窗口、動態規劃、加強堆、二叉樹遞歸套路 等。 還沒讀過的小伙伴可以關注一下&#xff0c;在主頁中點擊對應鏈接查看哦~ 接下來的一段時間&#xff0c;將持續 「力扣高頻題」 系列文章&#xff0c;想刷 …

Java基礎知識-線程池

1、為什么要用線程池&#xff1f; 創建線程要花費昂貴的資源和時間&#xff0c;如果任務來了才創建線程那么響應時間會變長&#xff0c;而且一個進程能創建的線程數 有限。為了避免這些問題&#xff0c;在程序啟動的時候就創建若干線程來響應處理&#xff0c;它們被稱為線程池&…

使用pywinauto自動重連easyconnect

啟動easyconnect后&#xff0c;運行該腳本&#xff0c;實現自動重連。需要填一下連接的地址&#xff0c;用戶名和密碼(替換一下腳本里的xxx) from pywinauto import application from pywinauto import timings import time# 初始化應用程序對象 app1 application.Applicatio…

2710. 移除字符串中的尾隨零 Easy

給你一個用字符串表示的正整數 num &#xff0c;請你以字符串形式返回不含尾隨零的整數 num 。 示例 1&#xff1a; 輸入&#xff1a;num "51230100" 輸出&#xff1a;"512301" 解釋&#xff1a;整數 "51230100" 有 2 個尾隨零&#xff0c;移…