feedgeneratorでRSS生成

import feedgenerator

feed = feedgenerator.Rss201rev2Feed(
    title="Poynter E-Media Tidbits",
    link="http://www.poynter.org/column.asp?id=31",
    description=
    "A group Weblog by the sharpest minds in online media/journalism/publishing.",
    language="en", )

feed.add_item(
    title="Hello",
    link="http://www.holovaty.com/test/",
    description="Testing.")

with open('test.rss', 'w') as fp:
    feed.write(fp, 'utf-8')

英語だと問題ないが

import feedgenerator

feed = feedgenerator.Rss201rev2Feed(
    title="あいうえお",
    link="http://www.poynter.org/column.asp?id=31",
    description=
    "かきくけこ",
    language="ja", )

feed.add_item(
    title="Hello",
    link="http://www.holovaty.com/test/",
    description="さしすせそ")

with open('test.rss', 'w') as fp:
    feed.write(fp, 'utf-8')

print(feed.writeString('utf-8'))

日本語だとファイルに保存すると文字化け

printはきちんと日本語表示されている

どうもWindows10のPython3.6.2だとutf7で書き出されているみたい

UbuntuのPython3.5.2だとutf8で出力された

Windowsでutf8にするにはどうやればいいんだろう

今治市の避難準備情報、避難勧告、避難指示情報と避難所情報をスクレイピング

import datetime
import re
from urllib.parse import urljoin
from urllib.request import urlopen

from bs4 import BeautifulSoup


def put_refuge(url):

    html = urlopen(url).read()
    soup = BeautifulSoup(html, 'html.parser')

    title = soup.select_one('#main_container > h1, h3').get_text(strip=True)

    date_pattern = re.compile(
        '(\d{4})年(\d{1,2})月(\d{1,2})日[  ](\d{1,2})時(\d{1,2})分')
    result = date_pattern.search(title)

    if result:
        d = map(int, result.groups())

        pubdate = datetime.datetime(*d)

    description = soup.select_one('#main_container > p').get_text(strip=True)

    return title, description, url, pubdate


def scraping(url, css_select):

    html = urlopen(url).read()
    soup = BeautifulSoup(html, 'html.parser')

    result = [
        put_refuge(urljoin(url, i.get('href')))
        for i in soup.select(css_select)
    ]

    return result


if __name__ == '__main__':

    # 避難準備情報、避難勧告、避難指示情報

    urge = scraping('http://www.city.imabari.ehime.jp/bousai/kankoku/',
                    '#main_container > p > a')
    for i in urge:
        print('\n'.join(i[:3]))
        print('-' * 30)

    # 避難所情報

    shelter = scraping('http://www.city.imabari.ehime.jp/bousai/hinanjo/',
                       '#main_container > div > p > a')
    for i in shelter:
        print('\n'.join(i[:3]))
        print('-' * 30)

玉川ダムの貯水率をスクレイピング

from urllib.request import urlopen
from bs4 import BeautifulSoup
import datetime
import csv

# GRP = USR004:玉川ダム、USR005:台ダム

grp = 'USR004'

# KTM = 1:1時間毎、2:30分毎、3:10分毎

ktm = 1

# 現在の時刻の5分前を取得
now = datetime.datetime.now() - datetime.timedelta(minutes=5)

# 時間を60分・30分・10分単位に補正する

n = 60

if ktm == 2:
    n = 30
elif ktm == 3:
    n = 10

cut_time = now - datetime.timedelta(minutes=(now.minute % n))

url = 'http://183.176.244.72/cgi/170_USER_010_01.cgi?GID=170_USER_010&UI=U777&SI=00000&MNU=1&LO=88&BTY=IE6X&NDT=1&SK=0000000&DT={0}&GRP={1}&TPG=1&PG=1&KTM={2}'.format(
    cut_time.strftime('%Y%m%d%H%M'), grp, ktm)

# URL確認
print(url)

html = urlopen(url).read()

soup = BeautifulSoup(html, 'html5lib')

result = []
day = ''

for trs in soup.select('body > table:nth-of-type(7) > tbody > tr'):

    # 列 => セル => セル内の列 => セル内のセル の順に取得

    dam = [[[i.get_text(strip=True) for i in tr.select('td')]
            for tr in tds.select('tr')]
           for tds in trs.select('td > table > tbody')]

    # 行・列入替
    temp = list(map(list, zip(*dam)))

    for j in temp:

        # Flatten
        data = sum(j, [])

        # 日付なし補完

        if data[0]:
            day = data[0]
        else:
            data[0] = day

        result.append(data)

with open('result.tsv', 'w') as fw:
    writer = csv.writer(fw, dialect='excel-tab', lineterminator='\n')
    writer.writerows(result)

PDFの表をテキスト変換

tabula

ブラウザ用 tabula.technology

  • 範囲をぎりぎりにしてると文字が漏れるようなので大きめに選択
  • ページが多いとリピートで以降のページも選べるがときどき選択されないページがあるので一旦最終頁までスクロールしてから選択すると失敗しにくい。

※ ページ丸ごとや全ページする場合は下のコマンド用が失敗も少なくおすすめ

コマンド用 github.com

  • TSVだとセル内に改行があるとずれるのでCSV保存してから加工するとよい。
  • セルの中にきちんと文字の入っている表だと失敗は今のところない。
  • セル外にオーバーしている文字は線の付近の文字は消える。結合しているようなセルは大丈夫。
  • セル外にオーバーしているところがあると以降のセルがずれる。ページ単位
  • 0.9.1以降は全角英数字は半角、カナは全角に変換される。古いバージョン0.9.0だと変換なくそのまま。

PDFBOX

テキスト化だけならこちらがおすすめ

pdfbox.apache.org

xdoc2txtを使っていたがテキスト化できないPDFも多かったのでこちらに移行

java -jar pdfbox-app-2.y.z.jar ExtractText [OPTIONS] [Text file]

sortすると見た目通りに並ぶので使いやすい

tabulaだけだと文字が漏れてたりする場合があるので確認用にこちらのテキストと比較して文字漏れがないか確認している。

Apache Tika

Apache Tika – Apache Tika

java -jar tika-app-1.16.jar -g

Word

WordでPDFを開き、Excelにコピペ

JUSTPDF3

JUSTPDF3でWordに変換後、Excelにコピペ

PDFからExcelやテキストはOCRになって文字が変わる

PDFminer.sixでテキストが取得できない

Pythonクローリング&スクレイピング ―データ収集・解析のための実践開発ガイド―

サポートページ:Pythonクローリング&スクレイピング ―データ収集・解析のための実践開発ガイド―:|技術評論社

5-8_pdf\print_pdf_textboxes.pyのサンプルコードを試しているのですがテキストが取得できない

5-8_pdf\parse_pdf.pyで試すと

<LTPage(1) 0.000,0.000,841.920,595.320 rotate=0>
    <LTFigure(Xf4) 0.000,0.000,841.920,595.320 matrix=[1.00,0.00,0.00,1.00, (0.00,0.00)]>
        <LTChar 564.070,556.851,568.570,565.851 matrix=[1.00,0.00,0.00,1.00, (564.07,558.12)] font='ABCDEE+MS P明朝' adv=4.5 text='あ'>
        <LTChar 568.624,556.851,577.624,565.851 matrix=[1.00,0.00,0.00,1.00, (568.62,558.12)] font='ABCDEE+MS P明朝' adv=9.0 text='い'>
        <LTChar 577.624,556.851,586.624,565.851 matrix=[1.00,0.00,0.00,1.00, (577.62,558.12)] font='ABCDEE+MS P明朝' adv=9.0 text='う'>
        <LTChar 586.624,556.851,591.124,565.851 matrix=[1.00,0.00,0.00,1.00, (586.62,558.12)] font='ABCDEE+MS P明朝' adv=4.5 text='え'>
        <LTChar 591.178,556.851,600.178,565.851 matrix=[1.00,0.00,0.00,1.00, (591.18,558.12)] font='ABCDEE+MS P明朝' adv=9.0 text='お'>

LTFigureになっているとだめみたい

LTTextBoxHorizontalだと取得できる

LTFigureからLTTextBoxHorizontalに変換する方法ないのかな

pdf2txt.pyだとテキスト化されるのでPDFminer.sixでもできるみたい

厚生労働省のブラック企業リストをTSV変換

a244.hateblo.jp

tabulaでブラウザで範囲を指定してPDFからTSV変換できます。

tabula.technology

コマンド用

github.com

tabula-1.0.1-jar-with-dependencies.jarをダウンロードして

java -jar .\tabula-1.0.1-jar-with-dependencies.jar -o 170510-01.csv -p all -r .\170510-01.pdf

を実行

TSVだと改行でずれるのでいったんCSV保存してから改行削除等の加工をしてTSV保存するときれいにできます。

import csv
import re

with open('170510-01.csv', 'r') as fr:
    reader = csv.reader(fr, dialect='excel')

    header = ['企業・事業場名称', '所在地', '公表日', '違反法条', '事案概要', 'その他参考事項']

    data = []

    # 管轄 初期値
    dept_labor = ''

    # 最終更新日 初期値
    last_modified_date = ''

    # ヘッダー追加
    data.append(["管轄", "最終更新日"] + header)

    for row in reader:

        # 前後のスペース削除
        temp = [i.strip() for i in row]

        # ヘッダーはスキップ
        # 千葉労働局に「その他参考事項」がないので4まで比較
        if header[:5] == temp[:5]:
            continue

        if '最終更新日' in temp[0]:

            test = temp[0].replace('最終更新日:', ' ').split()

            dept_labor = test[-2]
            last_modified_date = test[-1]

        else:
            # 改行文字を削除
            for j in range(len(temp)):
                temp[j] = re.sub('\n', '', temp[j])

            # 違反法条ごとにコンマ追加
            temp[3] = re.sub('条(の\d{1,3})?', lambda m: m.group(0) + ', ',
                             temp[3]).rstrip(', ')

            # 送検後別項目があるとコンマ追加
            temp[5] = re.sub('H\d{1,2}\.\d{1,2}\.\d{1,2}',
                             lambda m: ', ' + m.group(0), temp[5]).lstrip(', ')

            data.append([dept_labor, last_modified_date] + temp)

with open('result.tsv', 'w') as fw:
    writer = csv.writer(fw, dialect='excel-tab', lineterminator='\n')
    writer.writerows(data)

スプラトゥーン2

imabari.hateblo.jp

7/21 バッグとコントローラーは届いた 7/22 本体が届くみたい

www.nintendo.co.jp

アカウントは作成済みだけどSwitchがないので先に進めない

www.ikaclo.jp

有線LANも購入済み