2022-09-25に更新

なにも知らない PHP スクレイピング。マンガ カウンティング

preface

うっかり 1995 -2002 くらいまで掲示板 / 文化に興味をもってしまった(スレッドフロート型掲示板という言葉が英語なのか日本語なのかという疑問がきっかけだった。)ことから Perl という古語を自習していて、並列して PHP についてのことも知りたいとおもい( 2001 以降、perl + c 言語製 2 ちゃんねる から、PHP 5 製ふたばちゃんねるのソースコードからのフォークで 4 chan8 chan と推移するため)、まずベーシックなスクレイピングするプログラムを書いてみる。

Rf. はじめてのあやしいわーるど:システム
【ゆっくりネット史解説】4スレ目~あやしいわーるど~
くずはすくりぷと Rev.0.1 Preview 9 (2000.9.3)
https://rentry.co/7m3tu
https://rentry.co/ukw3f/
https://rentry.co/ssno4

あめぞう歴史
http://history.amebbs.com/


PHP は、バージョンが違うとまるで別物のように思えるので、バージョンは 8 系とする。apache などの web サーバーは必要ない。

要約すると、
PHP scraping
で検索すると表示されたページ。
https://www.utakata.work/entry/php/webscraping-with-php-html-parser
ここに掲載しているコードをコピペで実行してみたら、理解できました。PHP 全く知らなかったですが。

以下は、実は 漫画Bank / La « mangabank.org » a disparu. という記事(ない)からの続きになっています。

PHP 8 インストール for debian

sudo apt install -y gnupg2 ca-certificates apt-transport-https software-properties-common lsb-release
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
wget -qO - https://packages.sury.org/php/apt.gpg | sudo apt-key add -
sudo apt update
sudo apt-get --no-install-recommends install php8

とすることで、apache 抜きで PHP8 がインストールされるかもしれない。
されないかもしれない。そこは追求する必要があって、まだこれで完璧というとこまで到達できない。バージョン管理の phpenv があるらしいのでいずれはそれで。

パッケージマネージャーは、composer というものがあるので、バージョン 2 系のものを使う。なぜなら、php-html-parser というモジュールを使いたいからで、composer2 では無事にインストールできたから。

スクレイピングについては、色々と常識と非常識があって、それらは考慮したいが、知らない、知る前にやってしまう、やってしまった方がいいこともある。というスタンスで、できるだけ非常識にならないように、非常識のキョクホクのサイトをスクレイピングしてみる。

さて。

composer 2 自体のインストールは、省略。これもまた、どうするのがベストかわからない。簡単な方法でできればよし。できなければ深掘りしていくことになるが、インストールはできないということはないはず。

php-html-parser のインストール。https://github.com/paquettg/php-html-parser

~$ composer require paquettg/php-html-parser

php-html-parser とは jQuery のような感じで、html を扱うものだと思う。
そういうものは、いろんな言語であって、go だと goquery、Lua だと lua-gumbo、Nim だと nimquery、julia だと Gumbo とかで、それぞれ自分自身を解説するとき jQuery みたいなやつだからーとだけかいてあることが多いために使い方を調べるのには苦労する。
だけれども、一度どこかでその無限に時間を浪費するかのような道通ると、どこかで別のに出会っても、多少違うがほとんど同じという経験をする。おそらくそのために解説が省かれるのだと思う。だいたいおなじなので、どれかで分かりやすい解説が見つかれば一通りやってみるのがいい。

つまりは、html のタグとかタグ内の要素だとかで検索してずるずるっと引っ張ってきて、タグで挟まれたテキストを抽出したり、タグを付け足したりということをするためのものだ。
全然わからなければ、正規表現のようなもので代用することもある程度可能なので、正規表現に無限に時間をかける道も通っておいたらいいのかもしれない。

たとえば、ながいながい html ドキュメントに、

<a href="http://example.com/">リンク</a>

みたいな箇所がたくさんあって、これらをずるっと全部抜き出して、配列に入れて吟味したい場合にfind("a")みたいにして a タグのものすべてを簡単にひっぱってこれるといいね、ということを満たすもので、タグの中の attribute href で判別して、それが含まれるもの全部をひっぱってくるとかの用途に使う。

$url_1 = "https://search.brave.com/search?q=kadokawa+川上";

$dom = new Dom();
$dom->loadFromUrl($url_1, $options);

$element_a = $dom->find('a'); // a tag のリンクのエレメント全部を配列 $element_a に集める

foreach($element_a as $index=>$link){
    echo $index . ' ' . $link->{'href'} . "\n\n";
}

だいたい用途が同じものの場合はドキュメントが省略されるので、だいたい同じもののドキュメントがあれば参考にする。
Simple HTML DOM documentation

scraping.php

<?php

require_once __DIR__ . '/vendor/autoload.php';

use PHPHtmlParser\Dom;
use PHPHtmlParser\Options;

$options = new Options();
$options->setEnforceEncoding('utf8');

$url1 = 'https://13dl.me/list/popular/';
function scrape($counter,$options,&$element_a){
        $titles = array();
        $next = "";

        foreach($element_a as $line){
                if(preg_match('/title/',"$line")) {
                        $div = $line->find('div');
                        if(preg_match('/div/',"$div")) {
                                $titles[] = $div->text;
                        }else{
                                if(preg_match('/Next/',"$line")){
                                        $attr = 'href';
                                        $next = $line->$attr;
                                }
                        }
                }else{
                        ;
                }
        }
        unset($element_a);

        foreach($titles as $xxxx){
                $counter ++;
                echo $counter . " title :" . $xxxx . "\n";
        }
        unset($titles);
        return array("$next",$counter);
}

$counter = 0;
while($url1 != ''){
        if(preg_match('/http/',"$url1")) {
        try {
                $dom = new Dom();
                $dom->loadFromUrl($url1, $options);
                $element_a = $dom->find('a');
                list($url1,$counter) = scrape($counter,$options,$element_a);
                unset($element_a);
                unset($dom);
        } catch (Exception $e) {
                $e->getMessage();
        }
        } else {
                die('stop:' . $url1);
        }       
}
die('End.'); 
?>
ツイッターでシェア
みんなに共有、忘れないようにメモ

view_list マンガサイトにつひて
第3回 ある一つのサイトについての
第4回 タイトルから書籍情報を探す。
第5回 漫画Bank / La « mangabank.org » a disparu.
第6回 `_why`
第7回 なにも知らない PHP スクレイピング。マンガ カウンティング

tomato

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント