最近在整理做过的项目时,发现了曾经的一个好玩的东西,长时间不用都快忘记生疏了,在这里做下总结。在之前的时间里,流行用python写爬虫脚本,我学的是php于是经过学习也用php写了个简单的爬虫,用于抓取数据。
首先:
用到的技术:
QueryList (相关文档:https://doc.querylist.cc/)
Medoo(轻量级php数据库框架:https://medoo.lvtao.net/)
jQuery元素选择器
ok!有了这些就够了,正是开始吧!
一、composer安装QueryList 、Medoo
具体的composer安装方法官方文档上都有,附上composer.json中的内容:
{
"require":{
"jaeger/querylist":"3.*",
"catfan/Medoo":"1.*"
}
}
二、测试数据库连接
在安装完成后,首先写个脚本测试下,Medoo连接数据库是否成功:
<?php
require "vendor/autoload.php";
use Medoo\medoo;
$database = new medoo([
'database_type' => 'mysql',
'database_name' => '你的数据库名称',
'server' => 'localhost',
'username' => '用户名',
'password' => '密码',
'charset' => 'utf8'
]);
$data = $database->query("select version()")->fetchAll();
var_dump($data);
ok,能显示数据库版本信息就可以了,当然在测试之前,首先要创建相应的数据库。
三、爬取数据
要爬取数据首先看它的get请求,我以:http://blog.jobbole.com/category/career/为例
当点击下一页后,数字为2,同理,再点击下一页后,数字变为3,根据这一情况,就可以对页面中的数据进行爬取代码如下:
<?php
require "vendor/autoload.php";
use QL\QueryList;
use Medoo\medoo;
// 初始化配置
global $database;
$database = new medoo([
'database_type' => 'mysql',
'database_name' => 'crowl',
'server' => 'localhost',
'username' => 'root',
'password' => '密码就随意了',
'charset' => 'utf8'
]);
//主函数
function index()
{
echo "爬虫开始...\n";
for ($i = 1; $i < 21; $i++) {
echo "正在爬取第{$i}页\n";
$url = "http://blog.jobbole.com/category/career/page/{$i}/";
echo "url为{$url}\n";
$list_rule = [
'title' => ['#archive .archive-title','text'],
'detail_url' => ['#archive .post-thumb >a:first-child','href'],
'intro' => ['#archive .excerpt > p:first-child','text'],
'thumb' => ['#archive .post-thumb > a > img','src'],
'ctime' => ['#archive .post-meta > p:first-child','text','-a'],
];
$list_data = crawl_data($url, $list_rule);
foreach ($list_data as $key => $value) {
echo "开始获取<<{$list_data[$key]['title']}>>的详情\n";
//爬取详情
$datail_rule = [
'content' => ['.entry','html'],
];
$datail_data = crawl_data($value['detail_url'], $datail_rule);
//组合数据库
$db_data['article_title'] = $list_data[$key]['title'];
$db_data['article_thumb'] = $list_data[$key]['thumb'];
$db_data['article_intro'] = $list_data[$key]['intro'];
$db_data['article_content'] = $datail_data[0]['content'];
$db_data['article_ctime'] = find_date($list_data[$key]['ctime']);
//写入数据库
echo "开始写入数据库...\n";
$GLOBALS['database']->insert('article', $db_data);
$res_id = $GLOBALS['database']->id();
if ($res_id) {
echo "<<{$list_data[$key]['title']}>>写入数据库成功\n";
} else {
echo "<<{$list_data[$key]['title']}>>写入数据库失败\n";
$res = $GLOBALS['database']->error();
echo $res[2]."\n";
die();
}
}
print_r($list_data);
die;
}
echo "爬虫结束";
die();
}
//爬取数据函数
function crawl_data($url, $rule)
{
$data = QueryList::Query($url, $rule)->data;
return $data;
}
//从字符串中获取日期
function find_date($string)
{
$result = preg_match('/\d{4}\/\d{1,2}\/\d{1,2}/', $string, $matches);
if ($result) {
return $matches[0];
} else {
return "2018/01/01";
}
}
index();
好吧,一下子太多代码,一句句来解释;
首先在crowl数据库中创建一张表,表名为article;字段参考:
在创建完成后,可以开始写爬虫。首先根据:
http://blog.jobbole.com/category/career/page/2/ 中2的变化,可以为3,4,5.....
编写for循环从第1页爬取到第21页,当然有兴趣可以爬到最后一页。
把/page/后的数值修改下,
接下来就是关键的步骤了,学名叫做设置采集规则,主要用到的是jQuery的元素选择器,官方上用到的方法是:
在这里举个例子来说:
以获取文章的标题为例
定位到标题部分;
同理,其他需要的内容也是通过这样进行采集规则设置,之后就是开始进行采集:
$data = QueryList::Query($url, $rule)->data;
同时对新闻的详细内容,通过采集到的详情页面的地址,在设置详情页面的采集规则,采集主要内容。
最后把采集到的内容存入数据库中;
最后发起执行即可:
我擦。乱码,没关系,可以通过页面的方式进行查看,本地配置好站点信息;在脚本头部加入:
header("content-type:text/html;charset=utf-8");
好了,最后在试下(虽然数据库中已经加入,但是这个乱码看着还是难受)
查看下数据库:
好吧,完结!