代码之家  ›  专栏  ›  技术社区  ›  Shamoon

什么语言适合写网络爬虫?[关闭]

  •  3
  • Shamoon  · 技术社区  · 14 年前

    我有丰富的PHP经验,尽管我意识到对于大型网络爬虫来说,PHP可能不是最好的语言,因为一个进程不能无限期地运行。人们推荐什么语言?

    7 回复  |  直到 13 年前
        1
  •  0
  •   cripox    14 年前

    如果你知道自己在做什么。您将不需要Web服务器和Web应用程序,因为Web爬虫毕竟只是一个客户机。

        2
  •  10
  •   Chris Taylor    14 年前

    大多数语言可能是合理的,关键组件是

    1. 图书馆处理互联网协议
    2. 处理正则表达式的库
    3. 用于分析HTML内容的库

    今天,大多数语言都有对上述内容有良好支持的库,当然,您需要某种方法来保存可能是某种数据库的结果。

    比语言更重要的是理解你需要处理的所有概念。下面是一些可以帮助您入门的Python示例。

    http://www.example-code.com/python/pythonspider.asp

        3
  •  6
  •   Chuck    14 年前

    任何一种语言,只要有一个好的网络库,并且支持解析你想要爬行的格式,你就可以轻松使用。这些确实是唯一的条件。

        4
  •  1
  •   Dagg Nabbit    14 年前

    您可以考虑使用python和pygtkmozembed或pywebkitgtk加上javascript的组合来创建蜘蛛。

    在页面和所有其他脚本加载之后,可以在javascript中完成爬行。

    你将拥有少数几个支持javascript的网络蜘蛛之一,并且可能会发现其他蜘蛛看不到的隐藏内容:)

        5
  •  0
  •   Rohan Monga    14 年前

    当你可以复制的时候为什么要自己写? http://code.activestate.com/recipes/576551-simple-web-crawler/

    您可能需要在这里或那里解决一些问题,例如使用HTMLEntities而不是用&替换

        6
  •  0
  •   codersofthedark    13 年前

    当涉及到写多核/线程爬虫时,C是万能的上帝,但是它有它自己的复杂性。在C之后,有些人去Java(由于广泛的探索和使用),而另一些则转到Python。如果你有一个好的架构,我可以向你保证这三种语言不会限制你的效率。

    这个python代码是C curl实现,可以在一个不错的服务器上以300秒的速度爬行10000页左右。

    #! /usr/bin/env python
    # -*- coding: iso-8859-1 -*-
    # vi:ts=4:et
    # $Id: retriever-multi.py,v 1.29 2005/07/28 11:04:13 mfx Exp $
    
    #
    # Usage: python retriever-multi.py <file with URLs to fetch> [<# of
    #          concurrent connections>]
    #
    
    import sys
    import pycurl
    
    # We should ignore SIGPIPE when using pycurl.NOSIGNAL - see
    # the libcurl tutorial for more info.
    try:
        import signal
        from signal import SIGPIPE, SIG_IGN
        signal.signal(signal.SIGPIPE, signal.SIG_IGN)
    except ImportError:
        pass
    
    
    # Get args
    num_conn = 10
    try:
        if sys.argv[1] == "-":
            urls = sys.stdin.readlines()
        else:
            urls = open(sys.argv[1]).readlines()
        if len(sys.argv) >= 3:
            num_conn = int(sys.argv[2])
    except:
        print "Usage: %s <file with URLs to fetch> [<# of concurrent connections>]" % sys.argv[0]
        raise SystemExit
    
    
    # Make a queue with (url, filename) tuples
    queue = []
    for url in urls:
        url = url.strip()
        if not url or url[0] == "#":
            continue
        filename = "doc_%03d.dat" % (len(queue) + 1)
        queue.append((url, filename))
    
    
    # Check args
    assert queue, "no URLs given"
    num_urls = len(queue)
    num_conn = min(num_conn, num_urls)
    assert 1 <= num_conn <= 10000, "invalid number of concurrent connections"
    print "PycURL %s (compiled against 0x%x)" % (pycurl.version, pycurl.COMPILE_LIBCURL_VERSION_NUM)
    print "----- Getting", num_urls, "URLs using", num_conn, "connections -----"
    
    
    # Pre-allocate a list of curl objects
    m = pycurl.CurlMulti()
    m.handles = []
    for i in range(num_conn):
        c = pycurl.Curl()
        c.fp = None
        c.setopt(pycurl.FOLLOWLOCATION, 1)
        c.setopt(pycurl.MAXREDIRS, 5)
        c.setopt(pycurl.CONNECTTIMEOUT, 30)
        c.setopt(pycurl.TIMEOUT, 300)
        c.setopt(pycurl.NOSIGNAL, 1)
        m.handles.append(c)
    
    
    # Main loop
    freelist = m.handles[:]
    num_processed = 0
    while num_processed < num_urls:
        # If there is an url to process and a free curl object, add to multi stack
        while queue and freelist:
            url, filename = queue.pop(0)
            c = freelist.pop()
            c.fp = open(filename, "wb")
            c.setopt(pycurl.URL, url)
            c.setopt(pycurl.WRITEDATA, c.fp)
            m.add_handle(c)
            # store some info
            c.filename = filename
            c.url = url
        # Run the internal curl state machine for the multi stack
        while 1:
            ret, num_handles = m.perform()
            if ret != pycurl.E_CALL_MULTI_PERFORM:
                break
        # Check for curl objects which have terminated, and add them to the freelist
        while 1:
            num_q, ok_list, err_list = m.info_read()
            for c in ok_list:
                c.fp.close()
                c.fp = None
                m.remove_handle(c)
                print "Success:", c.filename, c.url, c.getinfo(pycurl.EFFECTIVE_URL)
                freelist.append(c)
            for c, errno, errmsg in err_list:
                c.fp.close()
                c.fp = None
                m.remove_handle(c)
                print "Failed: ", c.filename, c.url, errno, errmsg
                freelist.append(c)
            num_processed = num_processed + len(ok_list) + len(err_list)
            if num_q == 0:
                break
        # Currently no more I/O is pending, could do something in the meantime
        # (display a progress bar, etc.).
        # We just call select() to sleep until some more data is available.
        m.select(1.0)
    
    
    # Cleanup
    for c in m.handles:
        if c.fp is not None:
            c.fp.close()
            c.fp = None
        c.close()
    m.close()
    
        7
  •  -3
  •   ssube    14 年前

    C和C++可能是最好的两种语言,这只是一个你知道得更好,哪个更快(C很可能更容易)的问题。

    我不推荐使用python、javascript或php。与C族语言相比,它们的文本处理速度通常较慢。如果你想抓取网络中任何重要的部分,你需要尽可能快的速度。

    我以前用过c_和htmlagilitypack,它工作得比较好,而且很容易获取。使用大量与XML相同的命令来处理HTML的能力使它变得很好(我有在C中处理XML的经验)。

    您可能想测试可用的C语言解析库与C++解析库的速度。我知道在我的应用程序中,我每秒浏览60-70个相当混乱的页面,并从每个页面中提取大量数据(但这是一个布局相当稳定的站点)。

    编辑:我注意到你提到过访问数据库。C++和C语言都有与大多数常用数据库系统一起工作的库,从SQLite(这将是一个在几个站点上的快速爬行器)到中型引擎,比如MySQL和MSSQL,直到更大的DB引擎(我从未使用过任何一种语言的Oracle或DB2,但这是可能的)。