fork download
  1. #lang racket
  2.  
  3. (require html-parsing
  4. sxml
  5. (only-in srfi/13 string-delete)
  6. (only-in srfi/14 char-set-adjoin char-set:whitespace))
  7.  
  8. ;; パス設定
  9. (define *base*
  10. (path->directory-path
  11. ;; 以下は変更してO.K.
  12. ;; 特に、PCUSERはWindowsのユーザー名に書き換える事
  13. "C:\\Users\\PCUSER\\pictures"))
  14.  
  15. ;; デフォルトフォルダ名
  16. (define *sub*
  17. (path->directory-path
  18. ;; 以下は変更してO.K.
  19. "goo_blog"))
  20.  
  21. ;; Windowsのフォルダ名で使えない文字
  22. (define cs
  23. (char-set-adjoin char-set:whitespace
  24. #\\ #\/ #\: #\* #\? #\" #\< #\> #\|))
  25.  
  26. ;; DOSコマンド生成関数
  27. (define (command url p)
  28. (format "curl.exe --ssl-no-revoke -L \"~a\" -o \"~a\"" url (path->string (build-path p (last (string-split url "/"))))))
  29.  
  30. ;; ダウンローダー本体
  31. (define (downloader fname)
  32. ;; 基本のパスを組み立てる
  33. (let ((p (build-path *base* *sub*)))
  34. ;; 引っ越しデータファイル(fname)を開く
  35. (with-input-from-file fname
  36. (lambda ()
  37. ;; ファイルを一行づつ(read-line)読みながら繰り返し
  38. (let loop ((c (read-line)) (html '()) (p1 p))
  39. ;; 空行の場合例外が投げられるのでキャッチして次の処理へ
  40. (with-handlers ((exn:fail:contract?
  41. (lambda (e) (loop (read-line) html p1))))
  42. ;; ファイル末尾で処理を終了する
  43. (unless (eof-object? c)
  44. ;; 読み込んだ行をコロン(:)で分割
  45. (let ((lst (string-split c ":")))
  46. ;; 先頭(head)と残り全て(tail)へと分ける
  47. (let ((head (string-trim (car lst)))
  48. (tail (string-trim (string-join (cdr lst)))))
  49. (case head
  50. ;; スキップするheadは纏めて、次の処理へ
  51. (("AUTHOR" "PRIMARY CATEGORY" "STATUS" "ALLOW COMMENTS" "CONVERT BREAKS" "-----")
  52. (loop (read-line) html p1))
  53. ;; TITLEはフォルダを作成し次の処理へ
  54. (("TITLE") (let ((p2 (build-path p1 (string-delete cs tail))))
  55. (unless (directory-exists? p2)
  56. (make-directory p2))
  57. (loop (read-line) html p2)))
  58. ;; DATEはフォルダを作成し次の処理へ
  59. (("DATE") (let ((p3 (build-path p1 (string-delete cs tail))))
  60. (unless (directory-exists? p3)
  61. (make-directory p3))
  62. (loop (read-line) html p3)))
  63. ;; BODYは後続(空文字列)だけどhtmlへ積む
  64. (("BODY") (loop (read-line) (cons tail html) p1))
  65. ;; 一つの記事が終了
  66. ;; EyeCatchフォルダへのパスを作成
  67. (("--------") (let ((p4 (build-path p1 "EyeCatch"))
  68. ;; 写真アドレスを取り出してリストへ纏める
  69. (urls
  70. (map cadr
  71. ((sxpath '(// img @ src))
  72. (html->xexp (string-join (reverse html)))))))
  73. ;; EyeCatchフォルダを作成
  74. (unless (directory-exists? p4)
  75. (make-directory p4))
  76. ;; 1枚めの写真をEyeCatchフォルダへダウンロード
  77. (system (car urls) p4)
  78. ;; 残りはそのままダウンロード
  79. (for-each
  80. (lambda (url)
  81. (system (command url p1)))
  82. (cdr urls))
  83. (loop (read-line) '() p)))
  84. ;; 残りはHTML情報なんで一行丸ごとhtmlへと追加する
  85. (else (loop (read-line) (cons c html) p1))))))))))))
  86.  
  87. (module+ main
  88. (let ((p (build-path *base* *sub*)))
  89. (unless (directory-exists? p)
  90. (make-directory p)))
  91. (downloader (vector-ref (current-command-line-arguments) 0)))
Runtime error #stdin #stdout #stderr 0.55s 80948KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
standard-module-name-resolver: collection not found
  for module path: html-parsing
  collection: "html-parsing"
  in collection directories:
   /home/74eK3X/.racket/7.0/collects
   /usr/share/racket/collects
   ... [161 additional linked and package directories]
  context...:
   show-collection-err
   standard-module-name-resolver
   perform-require!78
   for-loop
   finish
   [repeats 1 more time]
   pass-1-and-2-loop
   module-begin-k
   expand-module16
   expand-capturing-lifts
   expand-single
   temp74_0
   compile16
   temp68_2
   loop