読者です 読者をやめる 読者になる 読者になる

SE(たぶん)の雑感記

一応SEやっている筆者の思ったことを書き連ねます。会計学もやってたので、両方を生かした記事を書きたいと考えています。

Powershellで指定したサイトからファイルを一括ダウンロードする

Powershell

おはようございます。

すごく間が空きました(;´・ω・)
転職したり、いろいろ忙しかったのです…

そんな事情は置いといて。

最近、いっぱいPDFファイルが公開されているサイトから、ファイルを一気にダウンロードできないものか
考えていたので、Powershellで作りました。

あくまで自分が楽できればいいので、これは引数で受け取れよ、とかはあると思いますが、そこは見逃してください。

.NETの機能は使っていきます。

・元URL指定

$targetUrl = "https://~/index.html";

#起点となるURL
$uri = New-Object System.Uri $targetUrl;

URLは適当に指定してください。
ここでは、System.Uriオブジェクトを作成しておきます。

・保存先指定

$saveDirectoryName = Get-Date -Format "yyyyMMddHHmmss";

$savePath = New-Item $saveDirectoryName -ItemType Directory -Force

Write-Output 出力先
Write-Output $savePath.FullName;

ここは適当で良いと思います。この通りに書くと、スクリプトの直下にフォルダが作成されます。
(正確にはカレントディレクトリかな?) 「サイトのURL + 時間」をフォルダ名にすると、見栄えが良いかも。

・ダウンロード

try{
    #Webページから、PDFへのリンクを取得
    $response = Invoke-WebRequest -Uri $targetUrl
    
    $links = $response.Links | Where-Object {$_.href -like "*.pdf"} | Select-Object -ExpandProperty href

    #個々のファイルダウンロード
    foreach($link in $links){
        #ファイル名抽出
        $fileName = Split-Path $link -Leaf
        
        #保存先作成(フォルダ + ファイル名)
        $outFilePath = Join-Path $savePath $fileName

        #DL対象ファイルのURL取得(Uriの機能で、絶対パスと相対パスをくっつける)
        $downloadUrl = New-Object System.Uri ($uri, $link)
        
        Invoke-WebRequest -Uri $downloadUrl -OutFile $outFilePath
        Write-Output "$fileName をダウンロードしました。"
    }
}catch [System.Net.WebException]{
    $statusCode = $_.Exception.Response.StatusCode;

    Write-Output エラー発生のため、処理を中断します。

    Write-Output "エラーステータス: $statusCode"
}

例外処理は適当です。(あくまで自分が(ry)

ちょっと解説していきます。

$response = Invoke-WebRequest -Uri $targetUrl

Invoke-WebRequestで、Webページ自体を取得します。
認証が必要なサイトなら、-Credentialでもつけてあげましょう。

$links = $response.Links | Where-Object {$_.href -like "*.pdf"} | Select-Object -ExpandProperty href

なんと、Invoke-WebRequestの戻り値のLinksプロパティは、そのサイトのすべてのリンクを返してくれます。
とはいえ、ページ遷移とかは今回いらないので、PDFへのリンクだけになるよう、Where-Objectでフィルタをかけます。別のファイルなら、そのフィルタをかけましょう。
そのあと、さらにhrefだけになるよう、Select-Objectを使います。
ブラウザに表示される文字を使いたい場合は、このSelect-Objectは不要かもしれないです。

ファイル名つけているところは省略します。

$downloadUrl = New-Object System.Uri ($uri, $link)

.NETのSystey.Uriクラスですが、絶対パスURIと文字列の相対パスを渡すと、相対パスが示す絶対パスを返してくれます!(日本語下手)
リンク:MSDNのヘルプ(Uriクラス)

正直、これがないと書くのが面倒です。これを知るまでは、実際のサイトの構成に合わせて、文字列を操作していました。

Invoke-WebRequest -Uri $downloadUrl -OutFile $outFilePath

ファイルのダウンロード操作です。
-OutFileでファイルパスを指定すると、そこにダウンロードしたファイルを作成してくれます。

あとはひたすらループで、ダウンロードしてくれます。

私はこれで、会計基準とかのファイルを一気にダウンロードしました(笑)

何かのご参考になれば。

初めてマークダウンで書いているので、見づらかったらすみません。

p.s. 全文をGitHubに上げて云々やりたい今日この頃。GitHub使い始めたばかりでわからない(´・ω・`)

おすすめの本 『達人プログラマー』

早速間が空きました…

 

今回、部門に新たに入ってくるメンバーへの研修をやることとなったので、久々に『達人プログラマー』を読みました。

 

www.amazon.co.jp

 

いやぁ、何度読んでもいい本ですね。

内容が古い部分があるのは否めないですけど、それでも示唆に富んだ本だと思います。

 

ぱっとわかる範囲だけでも、

  • DRY原則
  • 直交性
  • 可逆性
  • 契約による設計

等々、「プログラミングはできるけど、どのよう作っていくのかわからない」人に対しては、良い指針を示せる本です。

私自身、久々に目を通して、「あーなるほど」とか思いながら読んでました。

 

別途ツールを作りながらだったので、流し読みですが…

 

この本、今は絶版で、入手は困難なようです。私は4年半前に新品で手に入れました。

いい本だから、是非再販してほしいものです。『人月の神話』も装い新たに出たし。

テストについて

雑記

初記事は、いろいろ迷ったのですが、プログラムのテストについて語りたいと思います。

 

ちなみに、テストについては勉強しようと思っていますが、他の勉強ばかりしていて後回しになっています…

なので、素人の考えです。

 

テストと一言で言っても、思い浮かべることは、人によっていろいろだと思います。

私が浮かぶのをざっと挙げると、下みたいな感じです。

どんな開発プロジェクトであったとしても、テストにはそれなりの費用をかけているのだと思います。

ただ、テストへの力の入れ方を間違うと、いずれそのプロジェクトは破綻してしまうのではないか、と私は思ったりします。

 

単体テストの自動化は、どんどん導入するべきだと私は思いますが、古くから保守しているシステムだと、プログラム構造的の問題から単体テストが導入できないケースがあると思います。

(『エリック・エヴァンスのドメイン駆動設計』でアンチパターンとして挙がっている「利口なUI」ばかりのシステムとか)

 

そのシステムを書き換える(リファクタリングする)決定を通す風土が、チームや企業にあれば、メンバーやシステムにとって幸せでしょうが、テストの量を増やすことで保守し続けるという決定を下されるとします。

 

テストをたくさんする、という決定は一見問題ないように見えます。

ユーザーに対して、「このシステムは、この変更に対してこれだけの人数で、これだけテストしているから絶対大丈夫です!」と言うこともできるでしょう。

開発量をd、テスト量をtとしたら、「t = d * (係数)」とでも表したとします。

 

しかし、例えばこのシステムに対して「次回はdが3倍になる」改訂が加わるとしたら、tも3倍になるのでしょうか?

 

これは、確実にNoです。

上の係数は、一定値ではなく、dに関連して大きくなります。

結果として、tは指数関数的に増大します。

 

非常に単純な例を挙げると…

条件分岐1つに対し、必要なテストは「2」パターンです。

条件分岐が3つになったら、必要なテストは「8」パターンです。

 

たかが8パターンなら、問題ありません。

現実には、3つの条件分岐が9つになることもあります。

そのとき、先述のチームはテスト量を増やすことで、この改訂を乗り切ることができるのでしょうか…?ご想像にお任せします。

 

もう一つ、別の側面から見ます。

 

このシステムは、ユーザーから、要望等を多く受けているとします。

要望に応じて改訂を加えるということは、自ら「テスト量を増やす」という決定を下すことです。

外部から、提供時期に関して何らかの圧力があるとしたら(普通ありますが)、要望をかなえるために自ら工数を増やす決定を下すでしょうか?まず確実に、要望は後回しにすると思います。

そうすると、どれほど優れたシステムであっても、ユーザーはいずれ愛想を尽かして離れてしまうかもしれません…

 

まぁ、すべて想像に過ぎませんが。

 

 

私が思うのは、安直にテストを増やせばいいというのではなく、もっと前から手は打てるんだよ?ということです。

品質を保つには、リファクタリングしたり、テストを自動化したり、いろんな打つ手があるのだと思います。

 

 

テストと実装時間の関連については、『人月の神話』にも書かれているので、そちらを読むのもよいかもしれません。

 

では(´・ω・)ノシ

はじめましてのご挨拶

はじめまして。

 

システムエンジニアやってる hiro と申します!

だいたい6年ぐらい、プログラム書いたりいろいろしています。

 

 

ブログは、これまで何度か作ってきたのですが、ことごとく挫折…

今、またこうして始めているのは、Surface Pro 4を買ったおかげです。

 

スマホだと、がっつり文章を書く用途には向かないし、

PCではまとまった時間がないと書く気が起こらないし、… (言い訳続く)

 

でも、Surfaceなら寝る前とかでもちょっと起動して書けるし、便利そうなので、また始めようかな~と思って書いている次第です。

 

 

こんなこと書いていきたいな~と思っているのは、以下のような感じです。

  • プログラミングについて(C#大好き)
  • ドメイン駆動設計について(『エリック・エヴァンスドメイン駆動設計』読んで感動したので)
  • 読んだ本について
  • その他、開発に関して徒然と

 

Surfaceについて書くのとかもいいですね。

ちなみに、新しいタイプカバーの打鍵感は素晴らしいです。今も布団に寝そべってカチカチやってますが、キックスタンドで安定しますし。

 

思ったことを書くつもりですが、誰かの何かの役に立てると、うれしいなぁという気持ちはあります。

できるだけ、役立つ情報を発信できればいいなぁと思います。

 

では (´・ω・)ノシ