一、采集文章总体思路:
1、正则抓取文章列表页,提取出所有文章的链接地址写到临时表
2、从数据库中读取出所有文章的链接并访问,然后正则匹配出文章的标题及内容写入文章表中。
二、其中两个需要注意的地方:
1、采集防死:
因为在采集的过程中程序需要进行很多操作,如果一次全部读出,再加上网络的一些问题(比如网速慢,网络不稳定),程序在采集的过程中便可能会出现页面超
时的情况,对此我想到采用一条一条读取录入的办法,即打开页面时每次只读取一条文章链接进行采集,然后跳转页面,这样的话便可以减轻程序运行的负担,同时
增加了程序运行的流畅度,这样在一定程度上减少了页面超时的问题。
2、采集文章中图片:
在采集功能刚做出进行测试的时候,我发现了一个问题,就是当文章中含有图片的话,因链接地址不对导致采集到本地的文章在浏览时图片无法显示。对于这个问
题,我想到先把文章图片采集到本地,之后将采集到文章里的图片链接替换为本地图片链接,便能解决图片不能显示的问题。
$con = str_replace(array 原始地址,array 替换地址,string 文章内容);//替换文章原始图片地址
在根据这个思路完成功能的时候又发现了一个问题,绝对路径与相对路径的问题。有的网站是使用的相对路径,有的使用的是绝对路径。为了使我们这个采集功能能够通用化,所以在采集图片的时候我添加了一个路径判断:
$img_exist = is_int(strpos(\'文章内容\',\'http\'));//如果匹配到的链接含有\'http\'字符就为绝对路径
然后将匹配到的图片路径使用file_get_contents()读取,使用file_put_contents()保存。这样远程的图片就被保存到了本地。
思路总结:
1、判断文章中是否有图片存在。 $img_exist = is_int(strpos(string 文章内容,\'<img\'));
2、判断图片链接是绝对路径还是相对路径。
3、依次遍历图片地址并保存到本地。
4、替换图片原始地址为本地地址。
5、入库。
附昨天写一个项目的时候的部分源码:
//判断文章内容中是否有图片标签
$img_exist = is_int(strpos($count[0][0],\'<img\'));
//如果有图片
if($img_exist){
//取出所有img标签并匹配其链接
$preImg = "/<[img|IMG].*?src=[\\'|\"](.*?(?:[\.gif|\.jpg|\.png|\.bmp|\.jpeg]))[\\'|\"].*?[\/]?>/";
preg_match_all($preImg,$count[0][0],$arr);//$count[0][0]为原始文章内容,下同
//判断图片路径是否为绝对路径
$http_exist = is_int(strpos($arr[1][0],\'http\'));
//如果是绝对路径
if($http_exist){
foreach($arr[1] as $v){
//读取图片
$img = file_get_contents($v);
//获取图片名
$picName = pathinfo($v);
//创建图片文件到本地
file_put_contents(\'public/uploads/\'.$picName[\'basename\'],$img);
//拼装本地链接地址(下载图片的保存地址)
$namePic[] = B_PUBLIC."/uploads/".$picName[\'basename\'];//B_PUBLIC是这个项目使用的一个框架中的,目的是获取公共资源路径
}
//替换所有图片链接为本地链接
$con = str_replace($arr[1],$namePic,$count[0][0]);//$con为被替换链接地址之后的文章内容
//然后执行入库操作
//如果不是绝对路径
}else{
$preImg = "/<[img|IMG].*?src=[\\'|\"](.*?(?:[\.gif|\.jpg|\.png]))[\\'|\"].*?[\/]?>/";
foreach($arr[1] as $v){
//获取图片前缀
$mainUrl = parse_url($urlList[0][\'url\']);
//读取图片
$img = file_get_contents($mainUrl[\'scheme\'].\'://\'.$mainUrl[\'host\'].$v);
//指定打开的文件
$picName = pathinfo($v); //获取图片名
//写入图片文件到本地
file_put_contents(\'public/uploads/\'.$picName[\'basename\'],$img);
//拼装本地链接地址(下载图片的保存地址)
$namePic[] = B_PUBLIC."/uploads/".$picName[\'basename\'];
}
//替换所有图片链接为本地链接
$con = str_replace($arr[1],$namePic,$count[0][0]);
//然后执行入库操作
}
//如果没有图片
}else{
//执行入库操作
}