整理了一下前段时间写的php微信公众号文章的爬虫,解决了微信的防=防盗链机制,这里对图片进行了统一管理。代码使用tp3框架写的,可以根据实情换成tp5或者laravel框架的代码。
爬虫的参数可自行修改,我这里是项目需要,传的验证参数
/**
* 进入url手动采集文章逻辑
*
*/
public function manual($centent_url,$cateidstring,$status)
{
$request = trim($centent_url);
//地址验证(不完整的验证,后补)
if (empty($request)){
$resdata["r"]=3;
return $resdata;
exit;
}
//抓取文章内容
$html = $this->getUrlContent($request);
$result = array();
//抓取文章主要内容
preg_match_all("/id=\"js_content\">(.*)<script/iUs",$html,$content,PREG_PATTERN_ORDER);
//dump($html);exit;
$content = "<div id='js_content'>".$content[1][0];
//$content变量的值是前面获取到的文章内容html
$content = str_replace("data-src","src",$content);
//$content变量的值是前面获取到的文章内容html
$content= str_replace("preview.html","player.html",$content);
//将视频地址中的&全部替换成&
// $content = str_replace("&","&",$content);
//$html变量的值是前面获取到的文章全部html
preg_match_all('/var msg_title = \"(.*?)\";/si',$html,$m);
$msg_title = $m[1][0];//文章标题
$res = $this->robotartmodel->where(array("title"=>$msg_title))->find();
if ($res){
$resdata["r"]=2;
return $resdata;
exit;
}
preg_match_all('/var msg_desc = \"(.*?)\";/si',$html,$m);
$msg_desc = $m[1][0];//文章标题
/*preg_match_all('/var round_head_img = \"(.*?)\";/si',$html,$m);
$head_img = $m[1][0];//公众号头像*/
preg_match_all('/var publish_time = \"(.*?)\";/si',$html,$m);
$temp = $m[1][0];//零时日期存储
preg_match('/([0-9]{4})-([0-9]{2})-([0-9]{2})/', $temp,$n);
$publish_time = $n[0];//获取发布时间
preg_match_all('/var msg_cdn_url = \"(.*?)\";/si',$html,$m);
$msg_cdn_url = $m[1][0];//首张图片
preg_match('/var nickname = \"(.*?)\";/si',$html,$m);
$category = $m[1];//公众号
// preg_match_all('/^https://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$/',$html,$m);
// $video_url = $m[1][0];//视频地址
//视频地址
//https://v.qq.com/x/page/*****.html 获取到的vid参数,将星号替换
preg_match_all('/src=\"(.*?)\"/si',$content,$m);//获取src集合
$imgUrl = $m[1];
$imagearr = $this->crabImage($msg_cdn_url);
//处理图片
//将图片下载到本地文件夹中
$savepath = array();
foreach ($imgUrl as $key => $value){
//这里的crabImage图片下载本地函数可以再前面的几篇文章中找一下
$res = $this->crabImage($value);
//保存后的地址存入$savepath中
$savepath[$key] = $res['save_path'];
}
//将$content中的图片地址全部替换成$save_path
foreach ($savepath as $k => $val){
$content = str_replace($imgUrl[$k],$val,$content);
}
$map['nickname']=$category;
//根据微信号名称判断事都已经保存在数据库中
$pubwechatinfo=$this->robotpubwechatmodel->where($map)->find();
if($pubwechatinfo){
$pubwcid = $pubwechatinfo['id'];
}else{
$map['status']=1;
$pubwcid=$this->robotpubwechatmodel->add($map);
}
$result['pubwcid']=$pubwcid;
//将替换过的内容部分再替换出原$html里的内容
$result['content'] = $content;
$result['title'] = $msg_title;
$result['description'] = $msg_desc;
$result['publish_time'] = $publish_time;
$result['create_time'] = date('Y-m-d H:i:s');
$result['image'] = $imagearr['save_path'];
$result['search_url'] = $request;
$result['status'] = $status;
$result["cateid"] = $cateidstring;
//文章的保存和处理
$data =$this->robotartmodel->add($result);
//将存储的文章信息写入分类表
/* $val = $article_category->insert(['category'=>$result['category']]);*/
//dump($pubwcid.'<br>'.$data);exit;
if($pubwcid && $data){
$resdata["r"]=1;
$resdata["artid"]=$data;
}else{
$resdata["r"]=0;
}
return $resdata;
}
/**
* 爬虫程序
* 从给定的url获取html内容
* @param string $url
* @return string
*/
function getUrlContent($request) {
$handle = fopen($request, "r");
if ($handle) {
$content = stream_get_contents($handle, -1);
//读取资源流到一个字符串,第二个参数需要读取的最大的字节数。默认是-1(读取全部的缓冲数据)
// $content = file_get_contents($url, 1024 * 1024);
//这里也可以用php的curl爬取网页内容,可将curl爬取方式封装在这里
return $content;
} else {
return false;
}
}