赞助商广告

最近在整理做过的项目时,发现了曾经的一个好玩的东西,长时间不用都快忘记生疏了,在这里做下总结。在之前的时间里,流行用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;字段参考:

20180617001928640.png

在创建完成后,可以开始写爬虫。首先根据:

http://blog.jobbole.com/category/career/page/2/ 中2的变化,可以为3,4,5.....

编写for循环从第1页爬取到第21页,当然有兴趣可以爬到最后一页。

把/page/后的数值修改下,

接下来就是关键的步骤了,学名叫做设置采集规则,主要用到的是jQuery的元素选择器,官方上用到的方法是:

20180617002844625.png

在这里举个例子来说:

以获取文章的标题为例

定位到标题部分;

同理,其他需要的内容也是通过这样进行采集规则设置,之后就是开始进行采集:

$data = QueryList::Query($url, $rule)->data;

同时对新闻的详细内容,通过采集到的详情页面的地址,在设置详情页面的采集规则,采集主要内容。

最后把采集到的内容存入数据库中;

最后发起执行即可:

我擦。乱码,没关系,可以通过页面的方式进行查看,本地配置好站点信息;在脚本头部加入:

header("content-type:text/html;charset=utf-8"); 

好了,最后在试下(虽然数据库中已经加入,但是这个乱码看着还是难受)

查看下数据库:

好吧,完结!