找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 文档 工具 设计
查看: 70|回复: 0

PHP 多线程爬取天涯帖子

[复制链接]

1万

主题

919

回帖

2万

积分

超级版主

教育辅助界扛把子

附加身份标识
精华
1
热心
2
听众
1
威望
57
贡献
11988
违规
0
书币
5681
注册时间
2020-4-8

论坛元老灌水之王

发表于 2022-12-27 02:57 | 显示全部楼层 |阅读模式
使用了querylist框架来解析dom

话不多说,上代码

[PHP] 纯文本查看 复制代码
<?php

namespace app\command\crawler;

use GuzzleHttp\Psr7\Response;
use QL\QueryList;

class Tianya
{
    protected $url = "";// 帖子地址

    protected $title;
    protected $author;
    protected $urls = [];
    protected $mainPosts;
    protected $posts;

    public function execute(){
        $html = QueryList::get($this->url);
        $this->title = $html->find(".s_title")->text();
        $this->author = $this->handlerSymbol($html->find(".atl-info:eq(0)")->text());
        $pages = $html->find(".atl-pages:eq(0) a")->texts()->filter(function ($item){
            return is_numeric($item);
        })->all();

        if(!empty($pages)){
            $maxPage =  max($pages);
            $this->getUrls($maxPage);
        }
        $this->mainPosts = $html->rules([
            'author' => [".atl-info","text"],
            'content' => [".bbs-content","text"],
            'comments' => [".ir-list li","texts","-.ir-power -.ir-reply"],
        ])->range(".atl-item")->query()->getData()->all();
        $this->writeFile();
        $this->crawlOtherPage();
    }

    protected function getUrls($maxPage){
        if(is_numeric($maxPage)){
            for ($i=2;$i<=$maxPage;$i++){
                $this->urls[] =  str_replace("-1.shtml", "-{$i}.shtml", $this->url);
            }
        }
    }

    protected function writeFile(){
        $file = "{$this->title}.txt";
        if(is_file($file)){
            unlink($file);
        }
        $handler = fopen($file, "a+");
        fwrite($handler,$this->title.PHP_EOL);
        fwrite($handler,$this->author.PHP_EOL);
        foreach ($this->mainPosts as $item){
            fwrite($handler,$this->writeString($item['author']));
            fwrite($handler,$this->writeString($item['content']));
            fwrite($handler,$this->writeComment($item['comments']));
        }
        fclose($handler);
    }

    protected function writePosts(){
        $file = "{$this->title}.txt";
        $handler = fopen($file, "a+");
        sort($this->posts);
        foreach ($this->posts as $page){
            foreach ($page as $item){
                fwrite($handler,$this->writeString($item['author']));
                fwrite($handler,$this->writeString($item['content']));
                fwrite($handler,$this->writeComment($item['comments']));
            }
        }
        fclose($handler);
    }

    protected function crawlOtherPage(){
        if(!empty($this->urls)){
            $rules = [
                'author' => ['.atl-info','text'],
                'content' => ['.bbs-content','text'],
                'comments' => [".ir-list li","texts","-.ir-power -.ir-reply"],
            ];
            $range = '.atl-main .atl-item';
            QueryList::rules($rules)
                ->range($range)
                ->multiGet($this->urls)
                // 设置并发数为5
                ->concurrency(5)
                // 设置GuzzleHttp的一些其他选项
                ->withOptions([
                    'timeout' => 60
                ])
                // 设置HTTP Header
                ->withHeaders([
                    'User-Agent' => 'QueryList'
                ])
                // HTTP success回调函数
                ->success(function (QueryList $ql, Response $response, $index){
                    $data = $ql->queryData();
                    $this->posts[$index] = $data;
                })
                // HTTP error回调函数
                ->error(function (QueryList $ql, $reason, $index){
                    // ...
                })
                ->send();

            $this->writePosts();
        }

    }

    protected function handlerSymbol($string){
        return preg_replace('/\s+/', '   ',$string);
    }

    protected function writeString($string){
        return $this->handlerSymbol($string).PHP_EOL;
    }

    protected function writeComment($comments){
        $string = "";
        if($comments){
            $string.="评论:".PHP_EOL;
        }
        if(!empty($comments) && is_array($comments)){
            foreach ($comments  as $comment){
                $string .= "    ".$this->handlerSymbol($comment).PHP_EOL;
            }
        }

        $string.="\n\n\n\n\n";
        return $string;
    }
}


Great works are not done by strength, but by persistence! 历尽艰辛的飞升者,成了围剿孙悟空的十万天兵之一。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 需要先绑定手机号


免责声明:
本站所发布的第三方软件及资源(包括但不仅限于文字/图片/音频/视频等仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢某程序或某个资源,请支持正版软件及版权方利益,注册或购买,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To: admin@cdsy.xyz

QQ|Archiver|手机版|小黑屋|城东书院 ( 湘ICP备19021508号-1|湘公网安备 43102202000103号 )

GMT+8, 2024-4-29 17:47 , Processed in 0.043548 second(s), 27 queries .

Powered by Discuz! CDSY.XYZ

Copyright © 2019-2023, Tencent Cloud.

快速回复 返回顶部 返回列表