爬取新浪新闻的 PHP 爬虫实战
更新时间:2023-10-06PHP Web 爬虫介绍
PHP Web 爬虫是一个可以模拟浏览器行为,自动抓取网页内容并解析的程序。通过 PHP 语言的编写,爬虫可以自动化的获取网站数据,如新闻、图片、视频等,并将该数据进行分析与处理,生成所需的报表、文章等。和 Python 的 Requests 和 Beautiful Soup 模块类似,PHP 的 Web 爬虫同样需要第三方插件的支持。
// 安装第三方插件 GuzzleHttp require_once __DIR__ . '/vendor/autoload.php'; // 创建 GuzzleHttp 客户端对象 $client = new \GuzzleHttp\Client(); // 请求网站 $res = $client->request('GET', 'https://www.example.com'); // 输出响应数据 echo $res->getStatusCode(); echo $res->getBody();
爬虫执行流程
爬虫执行主要包括以下几个步骤:1、请求 URL 获取网页源代码;2、解析网页源代码,获取所需数据;3、将所需数据存储到数据库或输出至文件。对于新浪新闻网站的爬虫,由于新浪新闻的页面结构比较固定,以及文章详情页的 URL 规则一致,所以在编写爬虫时,可以采用如下实现流程。
// 请求新浪新闻页面 $url = 'http://www.sina.com.cn/'; $html = file_get_contents($url); // 解析页面获取新闻链接 $pattern = '/(.*?)<\/a>/'; preg_match_all($pattern, $html, $matches[]); // 请求新闻链接获取新闻详情 foreach ($matches as $match) { $news_url = $match[1]; $news_html = file_get_contents($news_url); // 解析获取新闻标题、内容、时间等数据 $pattern = '/(.*?)<\/title>.*? (.*?)<\/div>.*?(.*?)<\/span>/'; preg_match($pattern, $news_html, $detail); // 将新闻数据存储至数据库 $title = $detail[1]; $content = $detail[2]; $time = $detail[3]; $sql = "INSERT INTO sina_news (title, content, time) VALUES ('$title', '$content', '$time')"; mysqli_query($conn, $sql); }设置请求头与使用代理
为了避免请求被网站服务器拦截或者发生反爬虫,我们需要在请求头中添加一些参数,如 User-Agent、Accept-Language、Referer 等。此外,使用代理 IP 可以更有效地避免 IP 被封禁。下面是使用 GuzzleHttp 客户端设置请求头与代理的示例代码。
// 设置请求头 $headers = [ 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36', 'Accept-Language' => 'zh-CN,zh;q=0.9,en;q=0.8', 'Referer' => 'https://www.google.com/', 'Upgrade-Insecure-Requests' => '1', ]; $client = new \GuzzleHttp\Client([ 'headers' => $headers, ]); // 使用代理 $proxy = '192.168.1.1:1080'; $client = new \GuzzleHttp\Client([ 'proxy' => $proxy, ]);结合大数据与机器学习
在实际应用中,爬虫获取的数据量可能非常大,如何对这些数据进行保存、搜索和分析是必须要考虑的问题。此时,我们可以结合大数据和机器学习的技术,使用 Hadoop、Spark、Elasticsearch、Kibana 等工具来进行数据处理、存储和分析。对于新浪新闻爬虫,我们可以将爬取的数据存储至 Elasticsearch 中,并使用 Kibana 来展示数据分析结果。下面是使用 Elasticsearch 和 Kibana 的示例代码。
// Elasticsearch $search = '要搜索的关键字'; $params = [ 'index' => 'sina_news', 'type' => 'news', 'body' => [ 'query' => [ 'match' => [ 'content' => $search, ], ], ], ]; $response = $client->search($params); // Kibana SELECT COUNT(*) as count, DATE_FORMAT(time, '%Y-%m-%d') as date FROM sina_news GROUP BY date;