我有简单的HTML网站,其中包含我要解析的表格行。这些表有不定式(或关闭)页面,即页面http://example.com/?page=1
上有表格,页面http://example.com/?page=2
有下一个表格。
我已经有了基本功能,如:
(defn next-page [link] ...) ; given http://example.com/?page=2 returns http://example.com/?page=3
(defn parse [link] ...) ; return list of rows from table parsed from HTML
现在我想写一个函数,它接受起始链接并创建所有行的无限流 - 首先来自给定链接,然后是下一个链接。
示例:
table on site: http://example.com/?page=2
|--------------------|
| table 2 |
|--------------------|
| row1: value21 |
| row2: value22 |
| row3: value23 |
|--------------------|
(deftest should-parse
(is (=
'(value21 value22 value23)
(parse "http://example.com/?page=2"))))
table on site: http://example.com/?page=3
|--------------------|
| table 3 |
|--------------------|
| row1: value31 |
| row2: value32 |
|--------------------|
这应该是真的:
(defntest should-return-stream-with-rows
(is (=
'(value21 value22 value23 value31 value32)
(take 5 (row-stream "http://example.com/?page=2")))))
答案 0 :(得分:3)
如果我理解你,你可以使用mapcat
+ iterate
:
让我们的功能完全像你的那样(我猜)
(defn next-page [page-id] (inc page-id))
(defn parse [page-id]
(map #(str "link-" page-id "-" %)
(take (rand-int 10) (range))))
;; this one makes a random number of links:
;; (parse 0) => ("link-0-0" "link-0-1" "link-0-2" "link-0-3")
所以你可以使用这样的模型你想要的序列:
(defn all-links [starting-page-id]
(mapcat parse
(take-while some? (iterate next-page starting-page-id))))
它迭代所有next-page
结果与第一页的结果,然后连接所有结果。请注意,只要next-page
返回nil
,就会停止迭代(感谢take-while
)。
在repl中:
user> (take 20 (all-links 0))
("link-0-0" "link-0-1" "link-0-2" "link-0-3" "link-0-4"
"link-0-5" "link-1-0" "link-1-1" "link-2-0" "link-2-1"
"link-2-2" "link-3-0" "link-3-1" "link-3-2" "link-3-3"
"link-3-4" "link-3-5" "link-3-6" "link-3-7" "link-4-0")