哪种语言适合编写Web爬虫?

时间:2010-09-08 01:27:21

标签: php c++ python web-crawler

我有丰富的PHP经验,虽然我意识到PHP可能不是大型网络爬虫的最佳语言,因为进程无法无限期运行。人们建议使用哪种语言?

7 个答案:

答案 0 :(得分:10)

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

  1. 处理Internet Protcols的图书馆
  2. 处理正则表达式的库
  3. 解析HTML内容的库
  4. 今天大多数语言都有对上述语言有很好支持的库,当然你需要一些方法来保存可能是某种数据库的结果。

    更重要的是,而不是语言是理解你需要处理的所有概念。以下是一些可能有助于您入门的Python示例。

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

答案 1 :(得分:6)

您可以轻松使用任何语言使用良好的网络库,并支持解析您要抓取的格式。这些都是唯一的资格。

答案 2 :(得分:1)

您可以考虑使用python和PyGtkMozEmbed或PyWebKitGtk以及javascript的组合来创建您的蜘蛛。

可以在页面和所有其他脚本加载后在javascript中完成抓取。

你有少数支持javascript的网络蜘蛛之一,并且可能会收集其他人看不到的隐藏内容:)

答案 3 :(得分:0)

C ++ - 如果你知道你在做什么。您不需要Web服务器和Web应用程序,因为Web爬虫只是一个客户端。

答案 4 :(得分:0)

为什么要在复制http://code.activestate.com/recipes/576551-simple-web-crawler/

时自行编写

你可能需要在这里和那里修复一些东西,比如使用htmlentities而不是替换&与&

答案 5 :(得分:0)

在撰写多核/线程抓取工具时,C是最重要的,但它有自己的复杂功能。在C之后,一些人去JAVA(由于广泛的探索和使用),而其他人去Python。如果你有很好的架构,我可以向你保证这三种语言不会限制你的效率。

这个python代码是一个C Curl实现,可以在一台漂亮的服务器上在300秒内抓取大约10,000个页面

#! /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()

答案 6 :(得分:-3)

C#和C ++可能是最好的两种语言,它只是你知道的更好,哪种更快(C#可能更容易)。

我不推荐Python,Javascript或PHP。与C系列语言相比,它们在文本处理方面通常会更慢。如果您希望抓取网络的任何重要部分,您将需要所有速度。

我之前使用过C#和HtmlAgilityPack这样做,它的效果相对较好而且非常容易上手。像使用XML一样使用大量相同命令来处理HTML的能力使它变得很好(我有在C#中使用XML的经验)。

您可能希望测试可用的C#HTML解析库与C ++解析库的速度。我知道在我的应用程序中,我每秒运行60-70个相当混乱的页面并从每个页面中提取大量数据(但这是一个具有相当恒定布局的站点)。

编辑:我注意到你提到访问数据库。 C ++和C#都有可以与大多数常见数据库系统一起使用的库,从SQLite(对于几个站点上的快速爬虫很有用)到MySQL和MSSQL等中端引擎,直到更大的数据库引擎(我从未使用过Oracle)或者来自任何一种语言的DB2,但它是可能的。)