我正在编写这个程序,它就像在线论坛的网络爬虫。对于我抓取的每个论坛,我都需要做同样的事情:
- 登录
- 找到板子
- 找到帖子
- 找到帖子的永久链接
- 查找发帖人的用户名
- 等等
现在,虽然每个论坛都需要发生相同的逻辑,但每个论坛的实现是不同的。例如,每个论坛的每个登录表单的输入都不同。一个论坛可能有一个名为“用户名”的字段,另一个可能有一个名为“用户”的字段。其中一些步骤可能具有默认实现。例如,默认实现login
是不做任何事情(因为您不必登录某些论坛来抓取它)。
我所做的是创建了一个函数,其中包含所有这些步骤,crawl-forum
但实现是抽象的并在其他地方实现。我的问题是,使用这些实现的最佳方式是什么?crawl-forum
我试过的
1) 配置图
这是我到目前为止所尝试的。我向crawl-forum
名为configs
. 这是一个如下所示的地图数据结构:
{ :login login-function
:find-boards find-boards-function
...
}
调用的代码crawl-forum
负责填充该映射。我不喜欢的是configs
需要在整个crawl-forum
代码中传递。它到处添加一个新参数。此外,我还有一些用于处理默认实现的蹩脚的临时代码。
2) 多方法
我在 irc 上谈到了这一点,有人给了我一个想法,我应该为此使用多方法,因为它确实是多态行为。它们看起来像这样:
(defn get-site-key [& args] (first args))
(defmulti login get-site-key)
(defmethod login :default [site-key cookie-store] nil)
然后客户端代码必须在外部定义自己的多方法:
(defmethod login :forum-1 [site-key cookie-store] (do-something cookie-store))
我不喜欢的是,就像config
,我必须将site-key
in 传递给crawl-forum
函数,并且site-key
仍然必须在内部到处传递。此外,每个defmethod
人都必须将自己site-key
的参数作为参数传回,但他们都不会使用它。这只是进行调度的必要参数。不过,我真的很难找到一个完整的多方法教程,所以如果有更聪明的方法可以做到这一点,请告诉我。
有没有更好的第三种选择?有没有更好的方法来使用多方法?让我知道,谢谢。