PHP爬虫小demo
一直想弄个爬虫哈哈,由于自己的电脑python3用不了,所以就用学过的PHP写啦。
PHP初学者,哈哈 大神勿喷。
功能很简单,就是抓取指定有规则的网页中的信息,只需要你填写目标url和写一个简单的正则就OK
此版本暂且智能获取某一页的信息,最近会更新输入爬取到指定的页码抓取信息。
效果下图:
两个文件:
下面是前端的html的 页面源代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PHP原生爬虫小工具</title>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<link rel="stylesheet" >
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<style>
body{background: #F8F8FF;}
</style>
</head>
<body>
<h3 class="text-center">PHP原生爬虫小工具</h3>
<div class="container">
<div class="list-group">
<a href="#" class="list-group-item list-group-item-success">请输入抓取的链接url:格式:https://www.douyu.com/directory/game/jdqs</a>
<input type="text" name="inputUrl" class="form-control" id="inputUrl" value="https://www.douyu.com/directory/game/jdqs" />
<a href="#" class="list-group-item list-group-item-success">请输入你要匹配内容的正则:例如:'/<span class="dy-name ellipsis fl">(.*?)<\/span>/'</a>
<input type="text" name="inputPage" class="form-control" id="inputPat" value="">
<button class="btn btn-success btn-block" id="star">开始爬取</button>
</div>
<div class="alert alert-warning">
<p>
<span class="glyphicon glyphicon-paperclip"></span>
<span>使用方法:</span>
<p>抓取说明:一般都是抓取带有规则内容性的网页!</p>
</p>第一步:在第一个输入框的里面输入你要抓取信息的url地址,这个就不用多说啦,应该能都搞定!
<p>第二步:右击你的目标网页--->查看网页源代码--->然后在找到你需要的信息资源的位置最外层的a标签或者div标签p标签等等,就是它,你在看看上一条内容外边的class是否与这个相同,如果相同就开始写正则!</p>
<p>第三步:开始写正则(例子:<div class="desc">文本内容...</div>),然后把中间的文本内容用<strong> (.*?) </strong>代表查找所有,如果class类名像这样的(class="5656.html")中间的那个数字不是一样的,那么一样的方法,用<strong> (.*?) </strong>代替数字。同理只要是不一样的地方就用<strong> (.*?) </strong>来替换,一样的地方不用管!</p>
<p>
<span class="glyphicon glyphicon-info-sign"></span>注意:正则的两边一定要有//包围住!就像输入框中的例子!
</p>
</div>
<div class="form-group">
<label for="name">抓取的结果是:</label>
<pre id="txt1"></pre>
</div>
</div>
<script>
window.onload=function(){
//由于HTML上的那个vuale值不好写所以直接用js写啦
var inputPat =document.getElementById('inputPat');
inputPat.value = '/<span class="dy-name ellipsis fl">(.*?)<\\/span>/'
var inputUrl = document.getElementById('inputUrl');
var oStar = document.getElementById('star');
var oTxt = document.getElementById('txt1');
oStar.onclick=function(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState ==4){
var reInfo = xhr.responseText;
if(reInfo == ''){
oTxt.innerHTML = '结果为空,请检查你的正则是否正确!'
}else{
oTxt.innerHTML = reInfo;
}
}
}
xhr.open('get','function.php?url='+inputUrl.value+'&pat='+inputPat.value,true);
xhr.send();
}
}
</script>
</body>
</html>
还有一个封装的PHP类文件:
<?php
header('Content-type:text/html;charset=utf-8');
$url = $_GET['url'];
$pat = $_GET['pat'];
//封装了一些PHP爬虫的类,里面是一些爬虫常用的函数
class cuteCrawler {
/*
*@:brief获取网页源代码的函数
*/
public function getContentByFilegetcontents($url){
$content = file_get_contents($url);
return $content;
}
/*
*@:brief进行字符串的匹配的函数
*/
public function extract($content,$pat){
$matches = array();
preg_match_all($pat,$content,$matches);
return $matches;
//注意在外边要在这结果的后边加上 或者.....
}
/*
*@:brief将最后用正则得到的结果保存到txt文本中
*@:$reArr 是一个索引数组的资源集合
*@:$fengefu 是结果集中的中间分隔符号
*/
public function saveInfo($reArr,$fengefu){
$myfile = fopen('result.txt','w') or die ("Unable to open file!");
for($i=0;$i<count($reArr);$i++){
fwrite($myfile,$reArr[$i].$fengefu);
}
fclose($myfile);
}
/**
* @brief:这个是连接数据库的函数
* @sqlName:是需要你选择的数据库
*/
public function linkSql($username,$password,$sqlName){
$link = mysql_connect('localhost',$username,$password);
$choose = mysql_select_db($sqlName,$link);
if (!$choose) {
returnmysql_error();
}
}
/**
* @brief:这个是向数据库中添加数据的函数
*/
public function insetInfo($sql){
$query = mysql_query($sql);
if($query && mysql_affected_rows()>0){
return "数据添加成功";
}else{
return "数据添加失败";
}
}
/**
* @brief:判断用户的正则表达式中有多少个(.*?)
*/
public function countPat($pat){
$reCount = substr_count($pat,'(.*?)');
return $reCount;
}
/**
* @brief:测试各个函数并且返回最后的结果(仅供测数据试使用)
*/
public function testDemo(){
$url = "http://www.budejie.com/text/4";
$opop =self::getContentByFilegetcontents($url);
$pat ='/<a href="\/detail-(.*?).html">(.*?)<\/a>/';
$reinfo = self::extract($opop,$pat);
$countNum = self::countPat($pat);
$reinfo = $reinfo[$countNum];
return $reinfo;
}
/**
* @brief:返回传入值后的最终结果的函数(也就是用户看到的最终数据)
*/
public function returnAll($url,$pat){
$opop = self::getContentByFilegetcontents($url);
$reinfo = self::extract($opop,$pat);
$countNum = self::countPat($pat);
$reinfo = $reinfo[$countNum];
foreach ($reinfo as $key => $value) {
echo ($key+1).'-->'.$value.'';
}
}
}
//类的实例化
$crawler = new cuteCrawler();
///调用结果
$rereop = $crawler -> returnAll($url,$pat);
?>
zhengpengxin 发表于 2018-4-19 17:12
把搜索的结果集,插入到数据库中。哈哈
但是你源码中并没有数据库操作,感觉写这个有点多余吧?
还是说这个只是1.0版本,以后还有1.1、1.2、2.0版本增加入库的功能? yslook 发表于 2018-4-19 14:37
单线程,单页面抓取
要是多线程同时抓取或者单线程多页面抓取就厉害了
PHP抓取的效率感觉特慢 哈哈,那个多线程问题留给大神们开发吧 学习了, curl部分很精简 带cookie爬取的就不行了 没有抓下级页面的吗 楼主你这个水平学了差不多多久?准备学习完C++后学习py 单线程,单页面抓取
要是多线程同时抓取或者单线程多页面抓取就厉害了 什么工具 很好的教程,学习了,感谢楼主。 lihe1990 发表于 2018-4-19 14:28
没有抓下级页面的吗
暂时只有简单的抓取一指定的url,哈哈 待开发中.. 学IT的小屁孩 发表于 2018-4-19 14:34
楼主你这个水平学了差不多多久?准备学习完C++后学习py
这个是上学期 学完PHP课之后,闲着没事做的一个demo。