CommonCrawl PDFを漁る練習


はじめに

最近は大規模言語モデルを作っています。

データソースとして、ネット上のhtmlデータを収集したCommonCrawlは有名です。

しかし、htmlから抜き出したテキストは、あまり品質が高くないケースが多いです。
また、html版は多くの方が取り組んでおり、意外と日本語のテキストは枯渇気味です。

そこで今回は、CommonCrawlのPDF版を解析してみます。

コード一式(3/21追記)

以下のgitを使えばOKです。


ファイル一覧の取得と解析

ダウンロード

2021年のsnapshotのファイル一覧を取得します。

mkdir data
cd data

#download file list
wget https://digitalcorpora.s3.amazonaws.com/corpora/files/CC-MAIN-2021-31-PDF-UNTRUNCATED/metadata/cc-hosts-20230303.csv.gz

gzip -d cc-hosts-20230303.csv.gz

日本語ドメインの取得

今回は日本語のテキストを発掘します。

import pandas as pd
df=pd.read_csv("data/cc-hosts-20230303.csv")
print(df.shape) #全部で840万件

#日本ドメイン
ja_df=df[df["tld"]=="jp"]

#filenameが抜けてるrecordがあるので、削除
ja_df=ja_df[ja_df["file_name"]==ja_df["file_name"]]
#重複削除
ja_df = ja_df.drop_duplicates(subset=['file_name'])
ja_df

日本ドメインのpdfは、全部で約24万件だそうです。 軽く1000万件はあるような気がするので、思ったよりと少ないです。
(今後、もっとすごいcrawlingが出てくることを期待します。)

ドメインで絞ることもできます。

ja_df[ja_df["host"].str.find(".ac")>0].shape

大学系(.ac)では、1.9万件ほどのpdfがありました。

pdfの取得

pdfの格納場所

pdfの実データは、以下のページで整理されています。

細かく分割されてますが、例えば、
7921.zip には、7932000.pdf, 7932001.pdf, 7932002.pdf,…
というファイル群が格納されているようです。

.acドメインのpdfを集めてみる

全てのzipを落とすのは大変なので、.acドメインが沢山入っているzipを探してみます。

from collections import Counter

target_host=".ac"
target_df=ja_df[ja_df["host"].str.find(target_host)>0]
file_name_list=list(target_df["file_name"])

zip_index_list=[i[:4] for i in file_name_list]

counts=Counter(zip_index_list)
counts

解析によると、2928.zip に11個の".ac"ドメインのpdfが含まれているようです。

指定のindexのzipを落とす

関数定義

import requests
from zipfile import ZipFile
import os
def make_dir(path):
    if not os.path.exists(path):
        os.mkdir(path)


def get_url(target_zip_id):
    base_url="https://digitalcorpora.s3.amazonaws.com/corpora/files/CC-MAIN-2021-31-PDF-UNTRUNCATED/zipfiles"
    # 目標のZIP IDから範囲を生成する
    target_num = int(target_zip_id)
    start_range = (target_num // 1000) * 1000
    end_range = start_range + 999

    # 範囲を文字列で表現
    output_range = f"{start_range}-{end_range}"

    url=f"{base_url}/{output_range}/{target_zip_id}.zip"

    return url

def download_and_extract_zip(target_url, target_dir):
    # ZIPファイルをダウンロードするための一時ファイル名を生成
    temp_zip_path = os.path.join(target_dir, "temp.zip")
    
    # URLからZIPファイルをダウンロード
    response = requests.get(target_url)
    response.raise_for_status()  # エラーが発生した場合は例外を発生させる
    
    # ダウンロードした内容を一時ファイルに保存
    with open(temp_zip_path, 'wb') as temp_zip:
        temp_zip.write(response.content)
    
    # ZIPファイルを解凍
    with ZipFile(temp_zip_path, 'r') as zip_ref:
        zip_ref.extractall(target_dir)
    
    # 一時ファイルを削除
    os.remove(temp_zip_path)

実行 (ダウンロードに2、3分かかります)

target_zip_id="2928"
target_dir=f"data/{target_zip_id}"
make_dir(target_dir)
target_url=get_url(target_zip_id)
download_and_extract_zip(target_url, target_dir)

関連するpdfのリスト化

target_pdf_list=[i for i in file_name_list if i[:4]==target_zip_id]
target_pdf_list

実行結果

実際にファイルを確認してみると、確かに、大学っぽいpdfデータが入っていました。

まとめ

CommonCrawlのPDF版から、日本や指定のドメインのファイルを落とすコードを実装しました。
想定よりは、pdfデータが少なかったですが、通常のhtmlよりは上質なテキスト群を、CommonCrawlの枠組みで、入手できそうです。

pdfからtextを抜き出すプログラムの構築も必要そうです。


この記事が気に入ったらサポートをしてみませんか?