批量检查一百万个域的HTTP标头

时间:2012-07-05 19:06:32

标签: php python ruby http asynchronous

我正在查看一百万个域名的HTTP标题(即查找200/404/302)

此时我不需要身体HTML(虽然我可能稍后)所以最好使用HEAD请求而不是GET。我知道有些服务器不支持HEAD,并且愿意为了保持简单而牺牲那些不可检查的服务器。

我尝试了许多用PHP编写的解决方案(卷曲,多卷曲,几个DIY卷曲并行选项),但它们都不够快。

我很高兴使用任何语言,理想的结果是找到一个已经编译的C应用程序,只需要一个网址列表并吐出标题。例如,我使用预先推出的DNS应用程序来检查所有这些域的DNS设置,我所要做的就是打开一个管道并将其提供给域,并在它们进入时将答案吐回(不一定在同样的顺序)。

它需要是异步的或线程化才能足够快。

我探索了一些python选项(如Twisted框架和liburl2),但无法获得任何可靠的启动和运行。

希望有人可以帮我指出一个现成的解决方案!

2 个答案:

答案 0 :(得分:4)

查看gevent,尤其是基于它的图书馆。例如:https://github.com/gwik/geventhttpclient

答案 1 :(得分:0)

首先,对于那些由于鱼腥而贬低问题的人:谷歌就是这样做的。我非常感谢他们这样做。据我们所知,这位绅士或女士正在构建我们将在8年后使用的更好的搜索引擎。

但正如Rogue Coder所说:我们不应该全都不小心这样做。

关于这个问题:您无法获取域的标头。您可以从完成HTTP请求到URL获取标头。

至于解决方案:你可以将python与许多可用的http库之一一起使用,比如内置的httplib。由于请求的数量,您将需要使用线程并行地发出大量请求。下面的例子太简单了。在现实生活中,你会使用线程池。此外,有许多同时连接带来了自己的问题。那么:你想要多快?

import httplib
from threading import Thread
import time

hosts = [ 'www.google.com', 'www.yahoo.com', 'nos.nl' ]
responses = {}

class StatusChecker(Thread):

    def __init__(self, hostname):
        Thread.__init__(self)
        self.hostname = hostname

    def run(self):
        conn = httplib.HTTPConnection(self.hostname)
        conn.request("HEAD", "/index.html")
        res = conn.getresponse()
        responses[self.hostname] = res.status



if __name__ == "__main__":
    for h in hosts:
        StatusChecker(h).start()

    time.sleep(10)
    print responses

这会产生类似的结果:

$ python test.py
{'nos.nl': 200, 'www.yahoo.com': 301, 'www.google.com': 200}