PHPackages                             xixizizixixi/fatgoose - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. xixizizixixi/fatgoose

ActiveLibrary

xixizizixixi/fatgoose
=====================

1.0.9(5y ago)034Apache-2.0PHP

Since Nov 22Pushed 5y ago1 watchersCompare

[ Source](https://github.com/xixizizixixi/fatgoose)[ Packagist](https://packagist.org/packages/xixizizixixi/fatgoose)[ RSS](/packages/xixizizixixi-fatgoose/feed)WikiDiscussions master Synced yesterday

READMEChangelogDependencies (1)Versions (11)Used By (0)

一些注意点
-----

[](#一些注意点)

- 多进程可能出现的问题：因为多进程时各个进程之间的布隆过滤器无法保持一致，所以历史记录表和抓取任务表可能会出现重复内容。一般情况下也没必要使用多进程。
- 多个线程使用同一个tor链路：已实测如果有多个线程正在使用同一个tor链路（比如下载），此时用`kill -1 tor进程id`切换tor链路，不会对这些线程产生影响，新的线程会使用新的tor链路
- 长时间抓取需要考虑的问题：一般默认8小时后数据库连接将会断开，如果任务跑的时间特别长，修改mysql数据库配置的interactive\_timeout和wait\_timeout
- 目前下文中所指"自定义信息数组"包含：① 'task'键保存任务数组 ② 'opt'键保存抓取选项数组 ③ 'tor'键保存一个数组\['port'=&gt;端口号,'pid'=&gt;进程id\]
- 通过addTask()方法或者手动向抓取任务表中添加任务时需注意：因为先添加的任务先处理，所以添加任务的顺序会影响采集到的数据在数据库中的排列顺序。通常老的任务应该先添加，最新任务后添加。
- 即使返回响应状态码200，调用了抓取成功回调函数，也并不一定是"真正的抓取成功"了，因为返回的内容很可能是预期外的其他内容，所以务必进行特征检测，保证是需求的内容

快速开始 —— 抓取
----------

[](#快速开始--抓取)

```
//创建FatGoose对象
$fg=new FatGoose();

//设置抓取回调函数数组
$fg->setCallbacksArr();

//注册一个回调函数，自动传入自定义信息数组的引用，此回调函数在创建每个curl资源的时候都会调用
//这个回调函数可以(1)用返回值设置额外的或覆盖已存在的curl选项(2)往自定义信息数组里面注入额外信息
/*此回调函数大致结构如下，特别要注意参数是引用传递

    function(&$customInfoArr)
    {
        ...
        $customInfoArr['sum']=10000;     注入了额外信息
        ...
        return [CURLOPT_PROXYTYPE=>CURLPROXY_HTTP,CURLOPT_PROXY=>'127.0.0.1:1080'];   设置额外的curl选项
    }

*/
$fg->registerFuncExtraCurlOpt();

//添加初始抓取任务，要注意添加任务的顺序，先添加，先抓取。
//初始抓取任务只需添加一次，随后可注释掉
$fg->addTask();

//开始抓取
$fg->run();
```

快速开始 —— 监视
----------

[](#快速开始--监视)

```
//创建FatGoose对象
$fg=new FatGoose();

//设置监视回调函数数组
$fg->setMonitorCallbacksArr();

//开始监视
$fg->monitor();
```

抓取回调函数自动传入的参数情况
---------------

[](#抓取回调函数自动传入的参数情况)

- 静态方法mCrawl()用的回调函数没有中括号\[ \]里面的部分，也没有返回值。此方法主要用于一些简单的抓取和进行抓取测试。
- curl信息数组里面有什么可以看这个页面的"Return Values"部分
- onSuccess

    - p1:curl信息数组
    - p2:抓取到的内容
    - \[ p3:自定义信息数组 \]
    - \[ p4:pdo对象 \]

    这个回调函数主要有三个作用：

    ①对抓取到的内容进行分析，提取出自己想要的数据保存到数据库中

    ②返回一个数组，里面的url会成为下一级别的抓取任务。形式：

    - \[ \[ url , url , ...... \],false \] 这种形式默认extraInfo为null
    - \[ \[ \[ url,extraInfo \] , \[ url,extraInfo \] , ...... \] , false \]
    - 上面的extraInfo是个关联数组
    - 上面false改为true可临时无视布隆过滤器

    ③返回"reset"重置任务，任务状态重新设置为0；返回"ignore"则先跳过任务，任务状态会保持在1，以后再处理
- onSuccessWithUnexpectedCode

    - p1:curl信息数组
    - \[ p2:自定义信息数组 \]
    - \[ p3:pdo对象 \]

    返回"reset"重置任务，任务状态重新设置为0
- onFail

    - p1:目标url
    - p2:错误消息
    - p3:错误码
    - \[ p4:自定义信息数组 \]
    - \[ p5:pdo对象 \]

监视回调函数自动传入的参数情况
---------------

[](#监视回调函数自动传入的参数情况)

监视器对监视任务表中的任务进行监视（周期抓取），抓取成功后调用回调函数，回调函数中对页面是否更新进行判断。

- onMonitorSuccess
    - p1:curl信息数组
    - p2:抓取到的内容
    - p3:自定义信息数组
    - p4:pdo对象
    - p5:布隆过滤器对象

返回数组(形式同onSuccess的返回值)则向抓取任务表中追加新的任务(任务级别加1)，返回true则更新抓取任务表中与当前监视任务对应的任务为未抓取(0)状态以便再次抓取。

数据去重(布隆过滤器)
-----------

[](#数据去重布隆过滤器)

针对每个抓取的目标网站建立一个历史url集合，对即将添加到抓取任务表的url判断是否在这个集合中，没在才添加，并将这个新的url加入到集合中。

技术上采用布隆过滤器(bloomfilter)：时间和空间效率极高，有误判“结果在集合中，但实际不在集合中”，“结果不在集合中，实际也一定不在集合中”。所以使用bloomfilter最大的损失也就是有一些页面漏抓而已，这是完全可以承受的。

项目地址：  使用时直接参考即可

如果每次创建布隆过滤器对象都通过历史url表，当数据量特别大的时候整个过程会非常慢，而且很占内存。此时可考虑使用布隆过滤器缓存文件，如果缓存文件存在，则用缓存文件创建对象，否则还是通过历史url表创建对象。

注意：①缓存文件只适用于单进程，否则多个进程之间会相互覆盖②如果程序异常终止或强制终止，缓存文件会和历史url表不一致，此时应该手动删除缓存文件以便生成新的缓存文件

配置数组的配置项说明
----------

[](#配置数组的配置项说明)

```
$config=[

        //创建布隆过滤器时使用的预估条目数(确保添加到布隆过滤器中的条目数小于这个值)
        'item_num'=>1000000,
        //创建布隆过滤器时使用的误判几率
        'probability'=>0.0001,
        //无视布隆过滤器，开启时添加任务到任务表不会受到布隆过滤器的阻止
        'ignore_bf'=>false,
        //是否使用布隆过滤器缓存文件
        'use_bf_cache_file'=>false,
        //布隆过滤器缓存文件的路径
        'bf_cache_file_path'=>'/home/data_bf',

        //是否启用tor代理，必须保证当前环境已经创建了若干tor代理进程
        'use_tor'=>false,

        //tor代理进程的端口号和pid的映射数组 key是端口号 value是进程id
        //形如 [20001=>1234,20002=>1235,20003=>1236,......]
        'tor_ports_pids'=>[],

        //爬取失败重试次数
        'retry'=>1,

        //线程数
        'thread_num'=>15,

        //是否开启守护模式,周期性从抓取任务表中取任务进行抓取
        'daemon'=>false,
        //开启守护模式后间隔多少秒尝试进行一次爬取
        'daemon_interval'=>86400,

        //监视器时间间隔
        'monitor_interval'=>43200,

        //是否随机用户代理字符串
        'random_user_agent'=>false,
        //预定义的一系列用户代理字符串
        'user_agent'=>
            [ ],
        //curl默认选项
        'curl_opt'=>
            [
                CURLOPT_RETURNTRANSFER => true,  //抓取结果作为字符串返回，不输出到页面
                CURLOPT_CONNECTTIMEOUT => 60,  //连接60秒超时
                CURLOPT_TIMEOUT => 120, //函数执行120秒超时
                CURLOPT_FOLLOWLOCATION => true,  //跟踪重定向

                //设置Accept-Encoding请求头。同时能对压缩的响应内容解码
                CURLOPT_ENCODING => 'gzip, deflate',
                //设置用户代理字符串
                //百度蜘蛛 Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)
                //谷歌机器人 Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
                CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
                CURLOPT_HEADEROPT => CURLHEADER_UNIFIED, //向目标服务器和代理服务器的请求都使用CURLOPT_HTTPHEADER定义的请求头
                //构建更加真实的请求头
                CURLOPT_HTTPHEADER=> [
                    'Connection: close',
                    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
                    'Upgrade-Insecure-Requests: 1',
                    'Accept-Language: en-US,en;q=0.9,de;q=0.8,ja;q=0.7,ru;q=0.6,zh-CN;q=0.5,zh;q=0.4',
                    'Cache-Control: no-cache',
                ],

                /*设置代理*/
                //CURLOPT_PROXYTYPE=>CURLPROXY_HTTP,//设置代理类型CURLPROXY_HTTP或CURLPROXY_SOCKS5
                //CURLOPT_PROXY=>'127.0.0.1:1080',//设置代理的ip地址和端口号

                /*抓取https页面必要*/
                //CURLOPT_SSL_VERIFYPEER=>true,
                //CURLOPT_CAINFO=>'/home/cacert.pem',
                //CURLOPT_SSL_VERIFYHOST=>2,
            ],
        //默认数据库配置
        'database'=>
            [
                //服务器地址
                'host'=>'',
                //用户名
                'username'=>'',
                //密码
                'password'=>'',
                //端口
                'port'=>3306,

            ]

    ]
```

API说明
-----

[](#api说明)

- \_\_construct()

    创建FatGoose对象，参数依次为数据库名、任务表名、历史表名、监视表名、配置选项数组
- setCallbacksArr()

    设置抓取回调函数数组。此数组的格式为

    ```
    /*
       [
        ['0级抓取成功的回调函数','0级抓取成功但状态码有问题的回调函数','0级抓取失败的回调函数'],//0级任务回调函数
        ['1级抓取成功的回调函数','1级抓取成功但状态码有问题的回调函数','1级抓取失败的回调函数'],//1级任务回调函数
        ......
        ...... 以此类推可以无限级
       ]
    */
    ```
- setMonitorCallbacksArr()

    设置监视回调函数数组。此数组的格式为

    ```
    /*
       [0级监视任务成功的回调函数,1级监视任务成功的回调函数,2级监视任务成功的回调函数......]
    */
    ```
- addTask()

    用于添加抓取任务，第一个参数是任务数组，第二个参数是否忽略布隆过滤器(默认false)。任务数组的格式为

    ```
    /*
       [ [[url,extraInfo],level],[[url,extraInfo],level],...... ]
       或
       [ [url,level],[url,level],...... ]  样的形式则默认extraInfo为null
    */
    ```
- registerFuncExtraCurlOpt()

    注册一个回调函数，自动传入自定义信息数组的引用，此回调函数在创建每个curl资源的时候都会调用

    这个回调函数可以(1)用返回值设置额外的或覆盖已存在的curl选项(2)往自定义信息数组里面注入额外信息

    此回调函数大致结构如下，特别要注意参数是引用传递

    ```
    /*
       function(&$customInfoArr)
       {
           ...
           $customInfoArr['sum']=10000;     注入了额外信息
           ...
           return [CURLOPT_PROXYTYPE=>CURLPROXY_HTTP,CURLOPT_PROXY=>'127.0.0.1:1080'];   设置额外的curl选项
       }
    */
    ```
- run()

    开始爬取
- monitor()

    开始监视
- 静态方法 mCrawl()

    多线程异步爬虫，此方法功能有所简化，主要用于简单的抓取和抓取测试。传入的参数依次为，待抓取的页面(字符串或数组)、抓取成功的回调函数、响应状态码预期外的回调函数、抓取失败的回调函数、线程数、重试次数、抓取选项数组
- 静态方法 absoluteUrl()

    相对url转绝对url。传入的参数依次为，待转换的url(字符串或数组)、参照url，如果是目录后面带上/
- 静态方法 customArrayMerge()

    将第二个数组的数组项合并到第一个数组中，有则覆盖，无则追加，并且实现递归。

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity64

Established project with proven stability

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~38 days

Recently: every ~79 days

Total

10

Last Release

2014d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/35035426?v=4)[xixizizixixi](/maintainers/xixizizixixi)[@xixizizixixi](https://github.com/xixizizixixi)

### Embed Badge

![Health badge](/badges/xixizizixixi-fatgoose/health.svg)

```
[![Health](https://phpackages.com/badges/xixizizixixi-fatgoose/health.svg)](https://phpackages.com/packages/xixizizixixi-fatgoose)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
