参考文档1

参考文档2

这里是我自己写的一个小需求

<?php
/**
采集http://www.959.cn/school,即时更新的最新的文章内容;每分钟采集一次。采集结束后实时入库并展示。
*/
header("Content-Type: text/html;charset=utf-8");
date_default_timezone_set('PRC');
$con = mysqli_connect('127.0.0.1', 'xxxxx', 'xxxxx', 'xxxxx');
mysqli_set_charset($con,'UTF8'); // 日志位置
//把当前的最新一条文章的id.shtml的id 存入一个max.log的文件中,实时读取 实时更改
$log_path = '/home/logs';
if(!file_exists($log_path)){
mkdir($log_path,0755,true);
}
$max_log = $log_path.'/kecheng_max.log';
$path = './img/';
$max = file_get_contents($max_log) ? file_get_contents($max_log) : 4613925; //当前的最新一条文章的id.shtml的id //记录日志
$message_log = $log_path.'/kecheng_message.log'; $now_max = 0; //当前网站实际的最新一条的文章的id.shtml的id
$url = "http://www.959.cn/school/kecheng/";//要爬取的网址
$res = file_get_contents("compress.zlib://".$url);//curl封装方法
//var_dump($con);die;
preg_match_all('/<h3>.*<\/h3>/',$res,$arr_all);//文章列表内容
//var_dump($arr_all[0]);
foreach($arr_all[0] as $k => $v){
// 先去匹配a标签 如果不是a标签直接继续下一个
preg_match_all('/<a href="(.*)">.*<\/a>/',$v,$v_all);
if (empty($v_all[1])){// 不是a标签
continue;
} $title = strip_tags($v_all[0][0]); //文章标题
$href = $v_all[1][0];//url // 截取当前url的shtml前面的id
$href_one = substr($href, strrpos($href, '/')+1);
$href_id = substr($href_one, 0, strpos($href_one, '.')); if ($k === 0) {
$now_max = $href_id;
} if ($href_id <= $max){ // 只爬大于保存的最大id的数据
$max = file_put_contents($max_log, $now_max, LOCK_EX); // 爬完之后让maxid更新为最新的
break;
} // 获取标题缩略图
preg_match_all('/<img src="(.*)" alt="'.$title.'" \/>/',$res,$title_img);
$title_img_url = $title_img[1][0];
if(!file_exists($path)){
mkdir($path,0755,true);
}
$title_img = file_get_contents ("http:{$title_img_url}");
$cover_img_name = microtime_float().'.jpg';
file_put_contents($path.$cover_img_name, $title_img);
$cover_img = '/public/uploads/img/'.date('Y/md',time()).'/'.$cover_img_name; // 标题缩略图位置 // 获取文章内容
$article_res = file_get_contents("compress.zlib://".$href);
//var_dump($article_res);die;
$article_res = trimall($article_res);
//var_dump($article_res);die;
preg_match_all('/<div class="detail">(.*?)<\/div>/',$article_res,$article_all);//文章详情内容 $text = $article_all[1][0]; // 文章内容
//var_dump($text);die; //筛选图片 并下载到本地
preg_match_all('/<img .*? src="(.*?)" .*? \/>/',$article_all[1][0],$img_all); //文章详情图片
//preg_match_all('/<imgalt="创业项目"src="(.*?)"title="创业项目" \/>/',$article_all[0][0],$img_all); //文章详情图片
//var_dump($img_all[1]);
foreach($img_all[1] as $key => $value){
$message_img = file_get_contents ("http:{$value}");
$message_img_name = microtime_float().'.jpg';
file_put_contents($path.$message_img_name, $message_img); $text = str_replace($value,'/public/uploads/img/'.date('Y/md',time()).'/'.$message_img_name,$text);
}
// 去掉【如果还有什么问题点击留言咨询】 和 >>>>想了解更多创业资讯,点击咨询详情 和 其他的a标签
$text = preg_replace("/<a[^>]*>(.*?)<\/a>/is", "", $text);
//var_dump($text);die; // 入库数据
$cid = 2;// 1:行业资讯,2:创业故事
$source = '88加盟网';
$create_time = time();
$update_time = time(); // 入库前转码
$title = mb_convert_encoding($title,'UTF-8');
$text = mb_convert_encoding($text,'UTF-8');
//var_dump($title, $text); // 插入数据库
$sql = "insert into zs_message (cid, title, create_time, update_time, source, cover_img, text) values ($cid, '$title', $create_time, $update_time, '$source', '$cover_img', '$text')";
$result = mysqli_query($con,$sql); if ($result) {
$msg = "当前抓取的页面url为:{$href},入库sql为:{$sql},结果:入库成功";
} else {
$msg = "当前抓取的页面url为:{$href},入库sql为:{$sql},结果:入库失败";
}
file_put_contents($message_log, $msg, FILE_APPEND | LOCK_EX);
file_put_contents($message_log, "\n\r", FILE_APPEND | LOCK_EX); } function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return $sec.substr($usec,2,6);
} function trimall($str){
$qian=array("\n","\r");
return str_replace($qian, '', $str);
} function curl_get_contents($url,$cookie='',$referer='',$timeout=300,$ishead=0) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_TIMEOUT,$timeout);
curl_setopt($curl, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36');
if($cookie)
{
curl_setopt( $curl, CURLOPT_COOKIE,$cookie);
}
if($referer)
{
curl_setopt ($curl,CURLOPT_REFERER,$referer);
}
$ssl = substr($url, 0, 8) == "https://" ? TRUE : FALSE;
if ($ssl)
{
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
}
$res = curl_exec($curl);
return $res;
curl_close($curl);
}

爬虫主要的思路是:用正则去筛选我们爬取我们的页面,然后从列表页获取到的url,再一个个去爬取详情页的内容

注意事项:

  1. 如果用file_get_contens去获取内容的话,gzip压缩,会出现乱码的情况
file_get_contents("compress.zlib://".$url);

如是用的curl的话

function curl_get($url, $gzip=false){
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
if($gzip) curl_setopt($curl, CURLOPT_ENCODING, "gzip"); // 关键在这里
$content = curl_exec($curl);
curl_close($curl);
return $content;
}

无论页面是否经过gzip压缩,上述代码都可以正常工作!

参考出处

2.在获取到页面后,在匹配之前,一定要先把字符串中的\r\n空格换行都去掉,在进行匹配,否则会出现匹配为空的情况

function trimall($str){
$qian=array("\n","\r");
return str_replace($qian, '', $str);
}
// 处理页面源码,多行变单行
$htmlOneLine = preg_replace("/\r|\n|\t/","",$html);

3.去掉文章中的超链接或者将锚文本,只保留文字,去掉链接,去掉加粗格式

$text = preg_replace("/<a[^>]*>(.*?)<\/a>/is", "", $text);//去掉文章中的超链接
$str = preg_replace("/<a[^>]*>(.*?)<\/a>/is", "$1", $str);//只保留文字

4.生成图片的路径和文件名(参考)

$cover_img_name = microtime_float().'.jpg';
$cover_img = '/public/uploads/img/'.date('Y/md',time()).'/'.$cover_img_name;
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return $sec.substr($usec,2,6);
}

5.入库的时候,有可能会出现,存入的数据读出来全是???,或者乱码 要把页面设置为utf8,数据库设置为utf8

header("Content-Type: text/html;charset=utf-8");
date_default_timezone_set('PRC');
$con = mysqli_connect('127.0.0.1', 'xx', 'xx', 'xx');
mysqli_set_charset($con,'UTF8'); // 入库前转码
$title = mb_convert_encoding($title,'UTF-8');
$text = mb_convert_encoding($text,'UTF-8');

用php写爬虫去爬数据的更多相关文章

  1. 开发记录_自学Python写爬虫程序爬取csdn个人博客信息

    每天刷开csdn的博客,看到一整个页面,其实对我而言,我只想看看访问量有没有上涨而已... 于是萌生了一个想法: 想写一个爬虫程序把csdn博客上边的访问量和评论数都爬下来. 打算通过网络各种搜集资料 ...

  2. 使用selenium爬虫抓取数据

    写在前面 本来这篇文章该几个月前写的,后来忙着忙着就给忘记了.ps:事多有时候反倒会耽误事.几个月前,记得群里一朋友说想用selenium去爬数据,关于爬数据,一般是模拟访问某些固定网站,将自己关注的 ...

  3. 初次尝试python爬虫,爬取小说网站的小说。

    本次是小阿鹏,第一次通过python爬虫去爬一个小说网站的小说. 下面直接上菜. 1.首先我需要导入相应的包,这里我采用了第三方模块的架包,requests.requests是python实现的简单易 ...

  4. 怎么用Python写爬虫抓取网页数据

    机器学习首先面临的一个问题就是准备数据,数据的来源大概有这么几种:公司积累数据,购买,交换,政府机构及企业公开的数据,通过爬虫从网上抓取.本篇介绍怎么写一个爬虫从网上抓取公开的数据. 很多语言都可以写 ...

  5. python爬虫25 | 爬取下来的数据怎么保存? CSV 了解一下

    大家好 我是小帅b 是一个练习时长两年半的练习生 喜欢 唱! 跳! rap! 篮球! 敲代码! 装逼! 不好意思 我又走错片场了 接下来的几篇文章 小帅b将告诉你 如何将你爬取到的数据保存下来 有文本 ...

  6. Python写爬虫-爬甘农大学校新闻

    Python写网络爬虫(一) 关于Python: 学过C. 学过C++. 最后还是学Java来吃饭. 一直在Java的小世界里混迹. 有句话说: "Life is short, you ne ...

  7. 爬虫爬数据时,post数据乱码解决办法

    最近在写一个爬虫,目标网站是:http://zx.bjmemc.com.cn/,可能是为了防止被爬取数据,它给自身数据加了密.用谷歌自带的抓包工具也不能捕获到数据.于是下了Fiddler.     F ...

  8. python爬虫16 | 你,快去试试用多进程的方式重新去爬取豆瓣上的电影

    我们在之前的文章谈到了高效爬虫 在 python 中 多线程下的 GIL 锁会让多线程显得有点鸡肋 特别是在 CPU 密集型的代码下 多线程被 GIL 锁搞得效率不高 特别是对于多核的 CPU 来说 ...

  9. 爬虫爬数据时,post数据乱码解决的方法

    近期在写一个爬虫,目标站点是:http://zx.bjmemc.com.cn/.可能是为了防止被爬取数据,它给自身数据加了密. 用谷歌自带的抓包工具也不能捕获到数据. 于是下了Fiddler.     ...

随机推荐

  1. ExecutorException: A query was run and no Result Maps were found for the Mapped Statement ‘com.win.mall.dao.CartMapper.test’. It’s likely that neither a Result Type nor a Result Map was specified.

    ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'com.win.m ...

  2. C语言I博客作业008

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 http://edu.cnblogs.com/campus/zswxy/SE2019-3/homework/9982 我在这个课程的目标是 ...

  3. Java享元模式(Flyweight Pattern)

    享元模式(Flyweight Pattern)主要用于减少创建的对象数量,并减少内存占用并提高性能. 这种类型的设计模式属于结构模式,因为该模式提供了减少对象计数的方法,从而改善应用的对象结构. 享元 ...

  4. 重定向和转向的写法,重定向以post方式提交

    重转向保留跳转过来的Referer,路径不会变1 request.getRequestDispatcher("/eventweb/index.sp?loginId=" + logi ...

  5. 【Mock.js】前端模拟假数据,不用在手拼了

    [Mock.js]前端模拟假数据,不用在手拼了:https://www.jianshu.com/p/8579b703a4c1

  6. Neo4j百万级数据导入只需30s

    先上图:425万nodes.180万relationships只用了30s 243ms 项目需要生成关系图,开始考虑的是用Neo4j官网提供的REST API,从solr中查出2组数据先创建节点再创建 ...

  7. 个人公众号服务端开发Demo

    公众号出来很久了,也可以个人申请.知道公众号的服务端开发其实很简单,接口调用封装,数据存取,不外如是. 人一旦懒了,真的是 “无可救药” 了...现简单描述晚到的公众号HelloWorld 思路 公众 ...

  8. The Preliminary Contest for ICPC Asia Nanjing 2019 D. Robots

    题意:给出一个DAG,一只机器人从1点出发,等概率地选择一条出边走或者停留在原点,机器人的第k次行动消耗能量是k(无论是走还是停留都算一次行动).问1到n的期望. 解法:因为行动消耗的能量跟行动次数有 ...

  9. 虚拟机设置静态IP地址

    前言 NAT连接方式只能配置一次,配置好子网掩码和网关IP后,虚拟机NAT连接的ip段都是同一个ip段 1.菜单栏选择 编辑 -> 虚拟网络编辑器,打开虚拟网络编辑器对话框,选择Vmnet8 N ...

  10. Java集合框架的基础接口有哪些?

    Collection为集合层级的根接口.一个集合代表一组对象,这些对象即为它的元素.Java平台不提供这个接口任何直接的实现. Set是一个不能包含重复元素的集合.这个接口对数学集合抽象进行建模,被用 ...