用urllib实现的一个"类爬虫程序"

用urllib实现的一个"类爬虫程序"

毕设时写的一个抓取图片url"类爬虫程序",更新为第三个版本
#!/usr/bin/python
from htmllib import *
import formatter,urllib2,re,threading,sys,urllib
import urlparse

class imageParser(HTMLParser):
    def __init__(self,outfile,baseurl):
        self.out = outfile
        self.baseurl = baseurl
        HTMLParser.__init__(self,formatter.NullFormatter())
    def do_img(self,attrs):
        for attr in attrs:
            if attr[0] == "src":
                if attr[1][0] == "h":
                    self.out.write("%s\n"%(attr[1]))
                else:
                    self.out.write("%s\n"%(urlparse.urljoin(self.baseurl,attr[1])))
                    pass
class pageWorker (threading.Thread):
    def __init__(self,output,url,accepts,level):
        threading.Thread.__init__(self)
        self.output = output
        self.workurl = url
        self.acceptlist = accepts
        self.level = level
    def run(self):
        self.getUrlList(self.output,self.workurl,self.acceptlist,self.level)
    def getUrlList(self,output,url,accepts,level):
        if not level:
            return
        req = urllib2.Request(url)
        fd = 0
        try:
            fd = urllib2.urlopen(req)
        finally:
            if not fd:
                return

        info = fd.info()
        for accept in accepts:
            if re.match(accept,info["content-type"]):
                output.write("%s\n"%(url))

        if re.match("text/html.*",info["content-type"]):
                        parser = HTMLParser(formatter.NullFormatter())
                        try:
                                accepts.index("image/.*")
                                parser = imageParser(output,url)
                        except ValueError:
                                pass
                        parser.feed(fd.read())
                        for suburl in parser.anchorlist:
                pageWorker(output,suburl,accepts,level-1).start()
        fd.close()

#see http://www.iana.org/assignments/media-types/

if __name__ == "__main__":
        sys.stderr=open("err.log","w")
    accepts = []
    print sys.argv
    if len(sys.argv) >2:
        output = open(sys.argv[2],"w")
    else:
        output = sys.stdout
        
    argv = sys.argv[2:]
    for arg in argv:
                if arg == "image":
                        accepts.append("image/.*")
                elif arg == "video":
                        accepts.append("video/.*")
                elif arg == "audio":
                        accepts.append("audio/.*")
    rootpageworker = pageWorker(output,sys.argv[1],accepts,3)
    rootpageworker.run();

不知道找个javascript的虚拟机能不能分析那些动态页面

说实在的 这种程序除了炫耀外没多大意义

一个实际能用的上的爬虫要处理的东西很多的。。。
不是炫耀,我的目的看我签名
贴出来大家共同学习呗,我自己写过一个下程序从网易抓新闻的。只不过都是用正则去匹配,没有HTMLParser

突然想我想起公司一个同事成天说着自己写的爬虫爬虫啥的,把公司带宽都用光了。

无语唉。



QUOTE:
原帖由 xiaoyu9805119 于 2008-7-9 16:45 发表
贴出来大家共同学习呗,我自己写过一个下程序从网易抓新闻的。只不过都是用正则去匹配,没有HTMLParser

突然想我想起公司一个同事成天说着自己写的爬虫爬虫啥的,把公司带宽都用光了。

无语唉。

挂在服务器上
程序有bug哦,没有对argv做parser


QUOTE:
原帖由 vuleetu 于 2008-7-9 17:29 发表
程序有bug哦,没有对argv做parser

我不会用argument的解析库
我的建议是用正则 解析 HTMLParser 比起用正则 速度 相差大的 不信你可以去测试
你这个程序 我不说代码问题  

url去重复 这个。。。  还有就是python的虚拟机线程 不是无限的
所以你这样一个url一个线程。。。。

加油  这个程序还有很多地方可以改的


QUOTE:
原帖由 reiase 于 2008-7-9 14:06 发表
毕设时写的一个抓取图片url"类爬虫程序",这是第一个版本,第二个版本开线程开得太疯狂,有DDOS嫌疑,就不贴出来了。目前想添加cookie,javascript之类的功能进去
#!/usr/bin/python
from htmllib import *
...

感觉好乱。
这个脚本只是抓去抓取连接,所以我说是类爬虫。具体用途是给一个学长写的程序提供输入。找了下,找到第二个版本了。第二个版本线程粒度更小,因此性能更好,缺点是在windows上很容易到达线程数上限,推荐在Linux用
此外,目前该程序的瓶颈是网络的带宽和对方web服务器的响应速度,因此我认为没有必要考虑运算开销。
本来的目的是想抓去某个网站的所有图片,视频链接交给后边程序分析的,结果现在所有视频网站全用了flash,所以就放弃了视频部分,但是接口还是留着的
第三个版本在学校没有带回来,见谅
#!/usr/bin/python
from htmllib import *
from PyQt4 import *
import formatter,urllib2,re,threading,sys,urllib
import urlparse

class imageParser(HTMLParser):
    def __init__(self,outfile,baseurl):
        self.out = outfile
        self.baseurl = baseurl
        HTMLParser.__init__(self,formatter.NullFormatter())
    def do_img(self,attrs):
        for attr in attrs:
            if attr[0] == "src":
                if attr[1][0] == "h":
                    self.out.write("%s\n"%(attr[1]))
                else:
                    self.out.write("%s\n"%(urlparse.urljoin(self.baseurl,attr[1])))
                    pass
class pageWorker (threading.Thread):
    def __init__(self,output,url,accepts,level):
        threading.Thread.__init__(self)
        self.output = output
        self.workurl = url
        self.acceptlist = accepts
        self.level = level
    def run(self):
        self.getUrlList(self.output,self.workurl,self.acceptlist,self.level)
    def getUrlList(self,output,url,accepts,level):
        if not level:
            return
        req = urllib2.Request(url)
        fd = 0
        try:
            fd = urllib2.urlopen(req)
        finally:
            if not fd:
                return

        info = fd.info()
        for accept in accepts:
            if re.match(accept,info["content-type"]):
                output.write("%s\n"%(url))

        if re.match("text/html.*",info["content-type"]):
            parser = imageParser(output,url)
            parser.feed(fd.read())
            for suburl in parser.anchorlist:
                pageWorker(output,suburl,accepts,level-1).start()
        fd.close()

#see http://www.iana.org/assignments/media-types/

if __name__ == "__main__":
    accepts = ["image/.*"]
    print sys.argv
    if len(sys.argv) >2:
        output = open(sys.argv[2],"w")
    else:
        output = sys.stdout
    rootpageworker = pageWorker(output,sys.argv[1],accepts,3)
    rootpageworker.run();

本来还有个图形界面的,拿pyQT4做的,结果那个界面老出段错误(个人感觉是QT库的段错误),就给放弃了