您的位置:首页 > 编程语言 > PHP开发

PHP curl之爬虫初步

2015-10-08 15:25 621 查看
php的curl可以实现模拟http的各种请求,这也是php做网络爬虫的基础,也多用于接口api的调用。

这个时候有人就要发问了:为什么你特么不用file_get_contents?

curl的性能比它好,而且可以完成更多复杂的操作,不仅仅只是获取页面数据。

下面先分别介绍一些常用的函数。

curl_init 初始化一个curl对话

curl_exec 执行请求

curl_close 关闭一个curl对话

curl_setopt 设置curl参数,即传输选项

curl_errno 返回最后一次错误码,php已经定义了诸多错误枚举编码

curl_errror 返回一个保护当前会话最近一次错误的字符串

....

下面我先举一个例子,简单的get获取我博客首页的数据:

<?php
/**
* test get request
* User: freephp
* Date: 2015/10/8
* Time: 15:08
*/

$ch = curl_init();

// 2. 设置选项,包括URL
curl_setopt($ch, CURLOPT_URL, "http://www.cnblogs.com/freephp");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
// 3. 执行并获取HTML文档内容
$output = curl_exec($ch);
// 4. 释放curl句柄
curl_close($ch);

print_r($output);


就可以打印出首页的html代码。
也可把内容写入某个文件存储,这不就是爬虫的第一步么?

然后我们正则匹配过滤出文章的url,我封装了一个方法:


/**
* 从html内容中筛选链接
*
* @param string $web_content
* @return array
*/
function filterUrl($web_content){
$reg_tag_a = '/<[a|A].*?class="postTitle2".*?href=[\'\"]{0,1}([^>\'\"\ ]*).*?>/';
$result = preg_match_all($reg_tag_a,$web_content,$match_result);
if($result){
return $match_result[1];
}
}

print_r(filterUrl($output));


打印出来如图:




然后再遍历去请求这些url,然后拿到所有的文章内容。

(待续.....)

为了复用,我把curl请求发起,内容写入文件,过滤得到文章内容等操作封装成方法。最终的完整代码如下:

<?php
/**
* test get request
* User: freephp
* Date: 2015/10/8
* Time: 15:08
*/

/**
* 获取网页源码
*
* @param $url get方式请求的url
* @return mixed
*/
function getRquest($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
// 3. 执行并获取HTML文档内容
$output = curl_exec($ch);
// 4. 释放curl句柄
curl_close($ch);
return $output;
}

/**
* 从html内容中筛选链接
*
* @param string $web_content
* @return array
*/
function filterUrl($web_content)
{
$reg_tag_a = '/<[a|A].*?class="postTitle2".*?href=[\'\"]{0,1}([^>\'\"\ ]*).*?>/';
$result = preg_match_all($reg_tag_a, $web_content, $match_result);
if ($result) {
return $match_result[1];
}
}

/**
* 从html内容中筛选文章内容
*
* @param string $content
* @return array
*/
function filterContent($content)
{

$reg = '/<.*\"cnblogs_post_body\">(.*?)<\/div>/ism';
$result = preg_match_all($reg, $content, $match_result);
if ($result) {
return $match_result[1];
}
}

/**
* 抓取文章内容写入文件。
*
* @param string $fileName 存储文件名
* @param string $contents 文章内容
*/
function writeToFile($fileName, $contents)
{
$fp = fopen($fileName, 'w');

fwrite($fp, $contents);
fclose($fp);
}

$output = getRquest("http://www.cnblogs.com/freephp");

$articleUrls = filterUrl($output);
if (empty($articleUrls)) {
echo '获取文章url失败';
die();
}
$articleNum = count($articleUrls);
echo '总共文章为:', $articleNum, "\r\n";
foreach ($articleUrls as $url) {
echo '开始爬取url:', $url, "\r\n";
$out = getRquest($url);
$cont = filterContent($out);
$filename = str_replace('.html', '', str_replace('http://www.cnblogs.com/freephp/p/', '', $url));
writeToFile($filename . '.txt', $cont[0]);
echo '完成爬取url:', $url, "\r\n";
}


后面还会用使用post方式等用途的curl,等到那个时候再封装成工具类吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: