2018年11月

https://pkg.phpcomposer.com/#how-to-install-composer

全局安装
你可以将此文件放在任何地方。如果你把它放在系统的 PATH 目录中,你就能在全局访问它。 在类Unix系统中,你甚至可以在使用时不加 php 前缀。
你可以执行这些命令让 composer 在你的系统中进行全局调用:

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

注意: 如果上诉命令因为权限执行失败, 请使用 sudo 再次尝试运行 mv 那行命令。
现在只需要运行 composer 命令就可以使用 Composer 而不需要输入 php composer.phar。

局部安装
要真正获取 Composer,我们需要做两件事。首先安装 Composer (同样的,这意味着它将下载到你的项目中):

curl -sS https://getcomposer.org/installer | php

注意: 如果上述方法由于某些原因失败了,你还可以通过 php >下载安装器:

php -r "readfile('https://getcomposer.org/installer');" | php

使用镜像
有两种方式启用本镜像服务:
系统全局配置: 即将配置信息添加到 Composer 的全局配置文件 config.json 中。见“方法一”
单个项目配置: 将配置信息添加到某个项目的 composer.json 文件中。见“方法二”

方法一: 修改 composer 的全局配置文件(推荐方式)
打开命令行窗口(windows用户)或控制台(Linux、Mac 用户)并执行如下命令:
复制

composer config -g repo.packagist composer https://packagist.phpcomposer.com

方法二: 修改当前项目的 composer.json 配置文件:
打开命令行窗口(windows用户)或控制台(Linux、Mac 用户),进入你的项目的根目录(也就是 composer.json 文件所在目录),执行如下命令:
复制

composer config repo.packagist composer https://packagist.phpcomposer.com

上述命令将会在当前项目中的 composer.json 文件的末尾自动添加镜像的配置信息(你也可以自己手工添加):
复制

"repositories": {
    "packagist": {
        "type": "composer",
        "url": "https://packagist.phpcomposer.com"
    }
}

常见错误

Your requirements could not be resolved to an installable set of packages.

提示我的PHP 7版本太高,不符合composer.json需要的版本,但是在PHP 7下应该也是可以运行的,composer可以设置忽略版本匹配,命令是:

composer install --ignore-platform-reqs

or

composer update --ignore-platform-reqs

这是在虚拟机中执行composer,提示这个目录没有可写权限,composer无法缓存下载的包,这样就每次都得重新下载,把目录改成可写可读即可。

sudo chmod -R 777 /home/vagrant/.composer/cache/files/ 

用世界上最好的语言搞爬虫

基于querylist

How to use?

安装

通过Composer安装:

composer require jaeger/querylist

初探

看看PHP用QueryList做采集到底有多简洁吧!

<?php

use QL\QueryList;

//采集某页面所有的图片
$data = QueryList::get('http://cms.querylist.cc/bizhi/453.html')->find('img')->attrs('src');
//打印结果
print_r($data->all());

//采集某页面所有的超链接和超链接文本内容
//可以先手动获取要采集的页面源码
$html = file_get_contents('http://cms.querylist.cc/google/list_1.html');
//然后可以把页面源码或者HTML片段传给QueryList
$data = QueryList::html($html)->rules([  //设置采集规则
    // 采集所有a标签的href属性
    'link' => ['a','href'],
    // 采集所有a标签的文本内容
    'text' => ['a','text']
])->query()->getData();
//打印结果
print_r($data->all());

/**
 * 在线测试采集并查看采集结果:http://querylist.cc/querylist-test
 */

进阶

上面的采集结果有很多“杂质”,一定不会满足你的要求,来获取我们真正想要的结果。

<?php

// 采集该页面[正文内容]中所有的图片
$data = QueryList::get('http://cms.querylist.cc/bizhi/453.html')->find('.post_content img')->attrs('src');
//打印结果
print_r($data->all());


// 采集该页面文章列表中所有[文章]的超链接和超链接文本内容
$data = QueryList::get('http://cms.querylist.cc/google/list_1.html')->rules([
    'link' => ['h2>a','href','',function($content){
        //利用回调函数补全相对链接
        $baseUrl = 'http://cms.querylist.cc';
        return $baseUrl.$content;
    }],
    'text' => ['h2>a','text']
])->range('.cate_list li')->query()->getData();
//打印结果
print_r($data->all());

全貌

正如你看到的那样,使用QueryList做采集只需要编写采集规则即可!


<?php
/**
 * 下面来完整的演示采集一篇文章页的文章标题、发布日期和文章内容并实现图片本地化
 */

 //引入自动加载文件
require 'vendor/autoload.php';

use QL\QueryList;


//需要采集的目标页面
$page = 'http://cms.querylist.cc/news/566.html';
//采集规则
$reg = [
    //采集文章标题
    'title' => ['h1','text'],
    //采集文章发布日期,这里用到了QueryList的过滤功能,过滤掉span标签和a标签
    'date' => ['.pt_info','text','-span -a',function($content){
        //用回调函数进一步过滤出日期
        $arr = explode(' ',$content);
        return $arr[0];
    }],
    //采集文章正文内容,利用过滤功能去掉文章中的超链接,但保留超链接的文字,并去掉版权、JS代码等无用信息
    'content' => ['.post_content','html','a -.content_copyright -script']
];
$rang = '.content';
$ql = QueryList::get($page)->rules($reg)->range($rang)->query();

$data = $ql->getData(function($item){
  //利用回调函数下载文章中的图片并替换图片路径为本地路径
  //使用本例请确保当前目录下有image文件夹,并有写入权限
  $content = QueryList::html($item['content']);
  $content->find('img')->map(function($img){
      $src = 'http://cms.querylist.cc'.$img->src;
      $localSrc = 'image/'.md5($src).'.jpg';
      $stream = file_get_contents($src);
      file_put_contents($localSrc,$stream);
      $img->attr('src',$localSrc);
  });
  $item['content'] = $content->find('')->html();
  return $item;
});

//打印结果
print_r($data->all());

插件

QueryList拥有高度的模块化设计,扩展性强;通过插件可以轻松实现诸如:多线程采集、图片本地化、模拟浏览器行为、网络爬虫等强大功能!

<?php
/**
 * 下面来利用QueryList插件来组合上面的例子,实现多线程采集文章
 */
require 'vendor/autoload.php';

use QL\QueryList;
use QL\Ext\AbsoluteUrl;
use QL\Ext\CurlMulti;

// 注册插件
$ql = QueryList::use([
  AbsoluteUrl::class, // 转换URL相对路径到绝对路径
  CurlMulti::class    // Curl多线程采集
]);

// 获取文章列表链接集合,使用AbsoluteUrl插件转换URL相对路径到绝对路径.
$urls = $ql->get('http://cms.querylist.cc/news/list_2.html',[
    'param1' => 'testvalue',
    'params2' => 'somevalue'
],[
    'headers' => [
        'Referer' => 'https://querylist.cc/',
        'User-Agent' => 'testing/1.0',
        'Accept'     => 'application/json',
        'X-Foo'      => ['Bar', 'Baz'],
        'Cookie'    => 'abc=111;xxx=222'
    ]
])->absoluteUrl('http://cms.querylist.cc/news/list_2.html')->find('h2>a')->attrs('href')->all();


//使用CurlMulti多线程插件采集文档内容
$ql->rules([ // 设置采集规则
     'title'   => ['h1', 'text'],
     'date'    => ['.pt_info', 'text', '-span -a', function ($content) {
       //用回调函数进一步过滤出日期
       $arr = explode(' ', $content);
       return $arr[0];
     }],
     'content' => ['.post_content', 'html','a -.content_copyright -script']
   ])
  // 设置采集任务
   ->curlMulti($urls)
   // 每个任务成功完成调用此回调
   ->success(function (QueryList $ql, CurlMulti $curl, $r) {
     echo "Current url:{$r['info']['url']} \r\n";
     $data = $ql->range('.content')->query()->getData();
     print_r($data->all());
   })
   // 开始执行多线程采集
   ->start([
     // 最大并发数
     'maxThread' => 10,
     // 错误重试次数
     'maxTry'    => 3
   ]);

本来是
/activity.html?page=2


设置分页参数 url路径

$pages=input('param.page/d');
$options=[
        'page'=>$pages,
        'path'=>'/activity'."/page/[PAGE].html",
];
$activity = db('activity')->where(['type'=>$type,'status'=>1])->order('id desc')->paginate(8,false,$options);

之后
/activity/page/2.html