如何用PHP的curl高效抓取特定新闻网站的数据?
- 内容介绍
- 文章标签
- 相关推荐
在 PHP 开发中,抓取新闻网站的数据往往是个痛点:页面结构变化、需要登录、编码不统一、单线程效率低下等问题频繁出现。主要针对这些痛点,提供一套从列表页到详情页的完整抓取流程。并演示如何利用 cURL 进行高效并发请求。
使用者痛点汇总
1️⃣ 页面内容经常采用相对方法,需要拼接完整 URL;
2️⃣ 需要登录后才能访问的页面常见于付费订阅或会员专区;
3️⃣ 不同新闻网站使用多种字符编码,导致抓取后乱码;
4️⃣ 单线程循环抓取速度慢,特别是大规模新闻列表;
5️⃣ 目标站点会做反爬策略,如 IP 限流、验证码或动态 JS 加载内容。
概览这方面,从列表到详情的完整流程
$mh = curl_multi_init;// 开启多线程.
$ch = curl_init;
① 从新闻列表页获取标题和链接 ② 对每个链接发起请求,获取详情页 ③ 解析 DOM 或 XPath 提取正文 ④ 合并标题、链接、内容并输出或存储
1. 初始化 cURL 与多句柄管理
$mh = curl_multi_init;$ch = curl_init;不过,curl_setopt;curl_setopt,curl_setopt($ch。CURLOPT_USERAGENT,'Mozilla/5.0 ');老实说,curl_multi_add_handle;
2. 抓取新闻列表页
目标是提取
- 标题文本
- 相对或完整链接
$listUrl = 'https://example.com/news';老实说,$dom = new DOMDocument;@$dom->loadHTML);$xpath = new DOMXPath;$items = $xpath->query;$newsList =,foreach {
$title = trim;$href = $item->getAttribute;// 如果是相对方法,需要拼接
if ) {
$href = rtrim . '/' . ltrim;}
$newsList =;}
3. 并发抓取详情页
一次性把所有详情页加入多句柄,提高效率。说起来,
$handles =;foreach {
$chDetail = curl_init;curl_setopt,curl_setopt;// 若需模拟登录
if {
curl_setopt;curl_setopt,说起来,}
// 防止 HTTPS 验证错误
curl_setopt;curl_multi_add_handle;$handles =&$chDetail;老实说,}
// 执行所有请求
do {
$status=curl_multi_exec;
} while,foreach {
$html =&curl_multi_getcontent;// 处理编码差异
if {
$html=iconv;}
// DOM 解析正文
$doc=new DOMDocument;@$doc->loadHTML(mb_convert_encoding(
preg_replace。'HTML-ENTITIES','UTF-8'));$x=new DOMXPath;// 根据实际结构调整 XPath
$contentNode=$x->query->item;if {
foreach {
if
continue;其实,if
continue;// 收集正文文本
echo trim);按理说,}
}
}
curl_multi_close;// 清理临时句柄
foreach {curl_close;按理说,}
unset,其实,
注意事项这方面,
- Curl 的 Cookie 管理: 如果目标站点需要登录。可先用 $loginCh=curl_init 模拟登录,保存 Cookie 到文件,再在后续请求中使用该文件。
- 字符编码转换: 很多中文网站使用 GBK/GB2312,抓取后会出现乱码。可通过 iconv 将其转换为 UTF-8。
- Error Handling: 使用 @curl_errno 检查错误码;若出现网络错误,可重试一次或记录失败日志。
- Pagination & Looping: 若列表分页,需要解析下一页链接并递归执行上述流程。
- TOS & Legal: 务必确认目标网站允许爬虫抓取,否则请遵循 robots.txt 或联系站方授权。
4. 简易封装函数
// 单个 URL 抓取函数
function fetchPage: string|false{
global $COOKIEJAR;$ch=curlinit;curlsetoptarray(
$ch,);if){
curlsetoptarray(
$ch,);}
return @curlexec==false?false:@curlgetinfo==200?@curl_exec:false;}
>
与常用方法
- 面对页面编码不统一时用 iconv 转换为 UTF-8 是最快捷办法。老实说,
- 需要登陆的站点建议先用单独的 cURL 会话设置 cookie。接下来再把 cookie 文件传给后续请求。
- 单线程循环往往耗时数分钟甚至数小时使用 $mh=curl_multi_init 可以并行处理十几甚至上百个请求,明显提高抓取速度。
- 对于动态 JS 加载的内容,可考虑集成 Headless Chrome或者直接调用 API 接口。但这超出了纯 PHP cURL 的范畴。
- 任何爬虫操作都要尊重目标站点的 robots.txt 与服务条款;若发现异常,请及时停止以免被封 IP 或产生法律风险。
在 PHP 开发中,抓取新闻网站的数据往往是个痛点:页面结构变化、需要登录、编码不统一、单线程效率低下等问题频繁出现。主要针对这些痛点,提供一套从列表页到详情页的完整抓取流程。并演示如何利用 cURL 进行高效并发请求。
使用者痛点汇总
1️⃣ 页面内容经常采用相对方法,需要拼接完整 URL;
2️⃣ 需要登录后才能访问的页面常见于付费订阅或会员专区;
3️⃣ 不同新闻网站使用多种字符编码,导致抓取后乱码;
4️⃣ 单线程循环抓取速度慢,特别是大规模新闻列表;
5️⃣ 目标站点会做反爬策略,如 IP 限流、验证码或动态 JS 加载内容。
概览这方面,从列表到详情的完整流程
$mh = curl_multi_init;// 开启多线程.
$ch = curl_init;
① 从新闻列表页获取标题和链接 ② 对每个链接发起请求,获取详情页 ③ 解析 DOM 或 XPath 提取正文 ④ 合并标题、链接、内容并输出或存储
1. 初始化 cURL 与多句柄管理
$mh = curl_multi_init;$ch = curl_init;不过,curl_setopt;curl_setopt,curl_setopt($ch。CURLOPT_USERAGENT,'Mozilla/5.0 ');老实说,curl_multi_add_handle;
2. 抓取新闻列表页
目标是提取
- 标题文本
- 相对或完整链接
$listUrl = 'https://example.com/news';老实说,$dom = new DOMDocument;@$dom->loadHTML);$xpath = new DOMXPath;$items = $xpath->query;$newsList =,foreach {
$title = trim;$href = $item->getAttribute;// 如果是相对方法,需要拼接
if ) {
$href = rtrim . '/' . ltrim;}
$newsList =;}
3. 并发抓取详情页
一次性把所有详情页加入多句柄,提高效率。说起来,
$handles =;foreach {
$chDetail = curl_init;curl_setopt,curl_setopt;// 若需模拟登录
if {
curl_setopt;curl_setopt,说起来,}
// 防止 HTTPS 验证错误
curl_setopt;curl_multi_add_handle;$handles =&$chDetail;老实说,}
// 执行所有请求
do {
$status=curl_multi_exec;
} while,foreach {
$html =&curl_multi_getcontent;// 处理编码差异
if {
$html=iconv;}
// DOM 解析正文
$doc=new DOMDocument;@$doc->loadHTML(mb_convert_encoding(
preg_replace。'HTML-ENTITIES','UTF-8'));$x=new DOMXPath;// 根据实际结构调整 XPath
$contentNode=$x->query->item;if {
foreach {
if
continue;其实,if
continue;// 收集正文文本
echo trim);按理说,}
}
}
curl_multi_close;// 清理临时句柄
foreach {curl_close;按理说,}
unset,其实,
注意事项这方面,
- Curl 的 Cookie 管理: 如果目标站点需要登录。可先用 $loginCh=curl_init 模拟登录,保存 Cookie 到文件,再在后续请求中使用该文件。
- 字符编码转换: 很多中文网站使用 GBK/GB2312,抓取后会出现乱码。可通过 iconv 将其转换为 UTF-8。
- Error Handling: 使用 @curl_errno 检查错误码;若出现网络错误,可重试一次或记录失败日志。
- Pagination & Looping: 若列表分页,需要解析下一页链接并递归执行上述流程。
- TOS & Legal: 务必确认目标网站允许爬虫抓取,否则请遵循 robots.txt 或联系站方授权。
4. 简易封装函数
// 单个 URL 抓取函数
function fetchPage: string|false{
global $COOKIEJAR;$ch=curlinit;curlsetoptarray(
$ch,);if){
curlsetoptarray(
$ch,);}
return @curlexec==false?false:@curlgetinfo==200?@curl_exec:false;}
>
与常用方法
- 面对页面编码不统一时用 iconv 转换为 UTF-8 是最快捷办法。老实说,
- 需要登陆的站点建议先用单独的 cURL 会话设置 cookie。接下来再把 cookie 文件传给后续请求。
- 单线程循环往往耗时数分钟甚至数小时使用 $mh=curl_multi_init 可以并行处理十几甚至上百个请求,明显提高抓取速度。
- 对于动态 JS 加载的内容,可考虑集成 Headless Chrome或者直接调用 API 接口。但这超出了纯 PHP cURL 的范畴。
- 任何爬虫操作都要尊重目标站点的 robots.txt 与服务条款;若发现异常,请及时停止以免被封 IP 或产生法律风险。

