「プログラマが知るべき97のこと」をクローリングしてPDFを作る
はじめに
「プログラマが知るべき97のこと」というエッセイ集がWeb上で公開されていたのでクローリングしてPDF化してみました。
プロジェクトの作成
今回はクローリングスクリプトではScrapyを使用し、PDF化スクリプトではreportlabを使用します。
$ mkdir ninety_seven_things
$ cd ninety_seven_things
$ pipenv install scrapy reportlab
クローリングスクリプト
# crawler.py
from scrapy import Spider, Request
from functools import reduce
from operator import add
class NinetySevenThingsSpider(Spider):
name = 'ninety_seven_things_spider'
# クローリングを開始するURL
start_urls = ['https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/']
custom_settings = {
"DOWNLOAD_DELAY": 3, # ページ遷移間隔(秒)
"FEED_EXPORT_ENCODING": 'utf-8', # エンコード指定
}
def parse(self, response):
url_obj = response.xpath('/html/body/div/div/div/div/ol//li//a/@href')
full_urls = map(lambda href: response.urljoin(href.extract()), url_obj)
for full_url in full_urls:
yield Request(full_url, callback=self.output)
def output(self, response):
title = response.xpath('/html/body/div/div/article/h1/text()').extract_first()
author = response.xpath('/html/body/div/div/article/span/a/text()').extract_first()
body = reduce(add, map(lambda x: x.extract() + '\n', response.css('p::text')[:-3]))
yield {
'title': title,
'author': author,
'body': body.replace('。', '。\n')
}
クローリング
$ pipenv run scrapy runspider crawler.py -o output.json
PDF作成スクリプト
# pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet
import json
from functools import reduce
FILENAME = 'プログラマが知るべき97のこと.pdf'
pdfmetrics.registerFont(UnicodeCIDFont('HeiseiKakuGo-W5'))
styles=getSampleStyleSheet()
styles["Normal"].fontName = 'HeiseiKakuGo-W5'
doc = SimpleDocTemplate(FILENAME,pagisize=A4)
with open('output.json', 'r') as f:
texts = json.loads(f.read())
story = reduce(lambda x, y: x + y, map(lambda text: [
Paragraph('<font size=18>' + text['title'] + '</font>', styles["Normal"]),
Spacer(1, 18),
Paragraph('<font size=12> 著者: ' + text['author'] + '</font>', styles["Normal"]),
Spacer(1, 12),
Paragraph('<font size=10>' + text['body'] + '</font>', styles["Normal"]),
PageBreak()
], texts))
doc.build(story)
PDF作成
$ pipenv run python pdf.py
おわり
出典
プログラマが知るべき97のこと CC-by-3.0-USでライセンスされているようです。
Thanks for reading!