爬虫基础教程:php 程序实现单线程和多线程抓取数据
随着互联网技术的发展,爬虫技术也越来越被广泛应用于各种数据获取场景中。爬虫技术简单地说,就是模拟浏览器行为,对目标网站发起请求,获取网页内容,并进行数据提取和分析。
在 PHP 程序中,实现爬虫技术可以借助第三方组件,例如 cURL 和 Simple HTML DOM,这些组件大大简化了数据抓取的工作量。本篇文章将介绍如何使用 PHP 实现单线程和多线程方式进行数据抓取。
一. 单线程数据抓取
单线程数据抓取简单来说就是在一个线程中依次抓取目标站点的每个页面,然后对页面进行数据提取和解析。
在 PHP 中,可以使用 cURL 组件实现单页数据的获取,这里提供一个简单的示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php // 进行 cURL 初始化 $ch = curl_init(); // 设置 URL 和其他参数 curl_setopt( $ch , CURLOPT_URL, "http://example.com/" ); curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1); curl_setopt( $ch , CURLOPT_HEADER, 0); // 获取页面内容 $page_data = curl_exec( $ch ); // 关闭 cURL curl_close( $ch ); ?> |
通过以上代码,就可以获取指定网站的首页内容。接下来就可以通过 Simple HTML DOM 组件对页面内容进行分析,获取需要的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php // 引入 Simple HTML DOM 组件 require_once ( 'simple_html_dom.php' ); // 获取页面内容 $page_data = file_get_html( 'http://example.com/' ); // 获取某个节点 $node = $page_data ->find( '#content' , 0); // 获取节点文本 $text = $node ->plaintext; ?> |
通过以上代码,就可以获取指定网站首页中 id 为 content 的节点文本内容。
二. 多线程数据抓取
单线程数据抓取的局限性是速度慢,但在简单的数据获取场景中是可以满足需求的,但如果需要获取更多的数据,就需要考虑使用多线程方式进行抓取。
多线程数据抓取的原理是把数据请求和数据处理分成多个线程,同时进行,这样可以提高整个数据获取和分析的效率。在 PHP 中,可以使用多种方法实现多线程数据抓取,例如使用多个 curl 组件、使用多进程方式等。这里提供一个使用 curl 多线程方式的示例。
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 50 51 52 53 54 55 | <?php // 定义目标 URL 列表 $urls = array ( 'http://example.com/1.html' , 'http://example.com/2.html' , 'http://example.com/3.html' , 'http://example.com/4.html' , 'http://example.com/5.html' ); // 线程数 $max_threads = 5; $curlopt_array = array (); // 创建多个 cURL 组件 for ( $i = 0; $i < $max_threads ; $i ++) { $ch [ $i ] = curl_init(); } // 设置 cURL 参数 foreach ( $urls as $index => $url ) { $ch_index = $index % $max_threads ; curl_setopt( $ch [ $ch_index ], CURLOPT_URL, $url ); curl_setopt( $ch [ $ch_index ], CURLOPT_RETURNTRANSFER, 1); $curlopt_array [ $ch_index ][] = $ch [ $ch_index ]; } // 处理所有 cURL 请求 $mh = curl_multi_init(); foreach ( $curlopt_array as $ch_array ) { foreach ( $ch_array as $ch ) { curl_multi_add_handle( $mh , $ch ); } } // 执行多线程请求 $running = NULL; do { usleep(10000); curl_multi_exec( $mh , $running ); } while ( $running > 0); // 关闭所有 cURL foreach ( $ch as $ch ) { curl_multi_remove_handle( $mh , $ch ); curl_close( $ch ); } // 关闭 cURL 多线程 handler curl_multi_close( $mh ); ?> |
通过以上代码,就可以同时发送多个请求,从而实现多线程抓取数据的功能。然后,可以使用 Simple HTML DOM 组件对页面内容进行解析,获取需要的数据。
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | <?php // 定义目标 URL 列表 $urls = array ( 'http://example.com/' ); // 定义线程数 $max_threads = 5; // 定义处理函数 function handle_page_data( $page_data ) { // 解析 HTML 页面 $html = str_get_html( $page_data ); // 获取节点 $node = $html ->find( '#content' , 0); // 获取节点文本 $text = $node ->plaintext; // 处理数据 // ... } // 创建多个 cURL 组件 $ch = array (); for ( $i = 0; $i < $max_threads ; $i ++) { $ch [ $i ] = curl_init(); } // 设置 cURL 参数 $curlopt_array = array (); foreach ( $urls as $index => $url ) { $ch_index = $index % $max_threads ; curl_setopt( $ch [ $ch_index ], CURLOPT_URL, $url ); curl_setopt( $ch [ $ch_index ], CURLOPT_RETURNTRANSFER, 1); $curlopt_array [ $ch_index ][] = $ch [ $ch_index ]; } // 处理 cURL 请求 $mh = curl_multi_init(); foreach ( $curlopt_array as $ch_array ) { foreach ( $ch_array as $ch ) { curl_multi_add_handle( $mh , $ch ); } } // 处理多线程请求 $running = NULL; do { usleep(10000); curl_multi_exec( $mh , $running ); // 处理数据 while ( $done = curl_multi_info_read( $mh )) { $info = curl_getinfo( $done [ 'handle' ]); $page_data = curl_multi_getcontent( $done [ 'handle' ]); handle_page_data( $page_data ); curl_multi_remove_handle( $mh , $done [ 'handle' ]); curl_close( $done [ 'handle' ]); } } while ( $running > 0); // 关闭所有 cURL 组件 foreach ( $ch as $ch ) { curl_multi_remove_handle( $mh , $ch ); curl_close( $ch ); } // 关闭 cURL 多线程 handler curl_multi_close( $mh ); ?> |
以上代码是多线程方式获取页面内容,然后通过自定义函数 handle_page_data 对每页数据进行处理。
总结
本篇文章介绍了使用 PHP 实现爬虫技术的单线程和多线程方式,单线程方便易用,但速度较慢,多线程速度更快,但需要考虑组件之间的数据交互和处理。在实际应用中,需要根据具体需求选择适合的方案进行数据抓取和分析,从而最大化数据价值。