使用Haskell进行网络爬虫

53

目前Haskell中用于网站爬取的库处于什么状态?

为了提高自己对这门语言的熟练程度,我正在尝试使用Haskell处理更多的日常任务。

在Python中,我通常使用优秀的PyQuery库来完成这项工作。有没有类似于PyQuery简单易用的Haskell库呢?我已经研究了Tag Soup,虽然解析器本身很好,但是与其他语言相比,页面遍历起来似乎不是那么方便。

是否有更好的选择呢?


1
你认为TagSoup缺少什么? - Antoine Latter
1
解析文档的搜索功能似乎比其他语言的库更有限。通用函数(如“sections”)似乎还不错,但某些常见用途仍需要几行代码。例如,按类选择元素至少需要几行代码才能完成jquery中的单个调用。这对于一个项目来说并不是太糟糕,但我通常使用它来进行小型一次性项目。因此,我要么维护一些帮助程序,要么重复自己很多次。我错过了什么吗? - ricree
4个回答

36

http://hackage.haskell.org/package/shpider

Shpider是一个用于Haskell的Web自动化库。它允许您快速编写网络爬虫,对于简单情况(如遵循链接),甚至无需阅读页面源代码。

它有一些有用的功能,例如将页面上的相对链接转换为绝对链接,仅在给定域上授权事务的选项以及仅下载HTML文档的选项。

它还提供了填写表单的良好语法。

以下是一个示例:

 runShpider $ do
      download "http://apage.com"
      theForm : _ <- getFormsByAction "http://anotherpage.com"
      sendForm $ fillOutForm theForm $ pairs $ do
            "occupation" =: "unemployed Haskell programmer"
            "location" =: "mother's house"

(2018年更新 -- shpider已经过时,现在https://hackage.haskell.org/package/scalpel可能是一个好的替代品)


1
有趣。看起来shpider也可以用于Web测试。 - Michael Snoyman
迈克尔,你用它来测试了吗? - Qrilka
我在安装shpider到ghc 7.6.2上遇到了问题。 - Anton
+/-0: +1 界面很棒,非常直观,对单子使用得非常好。-1 无法与 ASPX 网站一起使用,无法正确解析表单。只是在寻找一个爬虫库,以便我不必处理低级别的 ASPX 网站疯狂... - recursion.ninja
这似乎依赖于已弃用的web-encodings,而web-encodings又依赖于过时的库。是否有更新的替代方案? - unhammer

23

从我在Haskell邮件列表中的搜索结果来看,TagSoup是解析网页的主要选择。例如:http://www.haskell.org/pipermail/haskell-cafe/2008-August/045721.html

至于Web抓取(如爬行、蜘蛛和缓存)的其他方面,我在http://hackage.haskell.org/package/上搜索了这些关键词,但没有找到什么有前途的东西。我甚至浏览了提到“http”的软件包,但没有什么特别引人注目的。

注意:我不是一个常规的 Haskell 用户,所以如果我错过了什么,希望其他人能发表评论。


Haskell XML 工具箱 (HXT) 值得一看:http://en.wikibooks.org/wiki/Haskell/XML - David J.
8
我可以为TagSoup作证:我曾经完全基于HTML抓取项目使用它。至于HTTP客户端包,我编写了http-enumerator是因为我没有看到任何好的替代品。 - Michael Snoyman
3
Scalpel是建立在TagSoup之上的工具。https://github.com/fimad/scalpel - guido
还有一个 https://github.com/bgamari/html-parse 宣称比 tagsoup 快8倍。 - unhammer

11
尽管我现在还是Haskell的初学者,但我坚信2012年的HTML解析必须使用CSS选择器,而目前推荐的库似乎没有使用这个原则。 其中一个可能性是HandsomeSoup,它是基于HXT构建的。

http://egonschiele.github.com/HandsomeSoup/

http://codingtales.com/2012/04/25/scraping-html-with-handsomesoup-in-haskell

这个页面关于HXT,它是HandsomeSoup所依赖的,将会对你有所帮助(你需要使用getText或deep getText):

http://adit.io/posts/2012-04-14-working_with_HTML_in_haskell.html

但另一个选择是dom-selector:

http://hackage.haskell.org/package/dom-selector

现在它是alpha版本,长期维护可能会成为一个问题。dom-selector的优点是,我无法使用HandsomeSoup处理Unicode字符。但是,dom-selector可以直接使用Unicode字符。

这个问题与以下内容相关: 在Haskell的HXT中是否可以使用Text或ByteString?

dom-selector基于html-conduit和xml-conduit,它们的维护似乎有保障。

编辑:请注意我的新答案,它基于lens解析。尽管本回答仍然很好,但我现在更倾向于使用其他方法。


1
HandsomeSoup是一个非常棒的库。谢谢分享,否则我就不知道该去哪里找了! - thegravian

6
我之前已经回答过这个问题,建议使用基于CSS选择器的解析方式,但是那个答案已经一年半了,现在我认为镜片可能是Haskell中更好的方法。实际上,你会得到类似于类型安全编译选择器的东西。
参见这个Reddit讨论,其中提供了几种选择。如果链接消失了,我复制了直接链接: 我还没有使用过它们,但如果我今天要编写解析HTML的新代码,我肯定会采用基于镜片的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接