免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 10352 | 回复: 25
打印 上一主题 下一主题

用urllib实现的一个"类爬虫程序" [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-09 14:06 |只看该作者 |倒序浏览
毕设时写的一个抓取图片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的虚拟机能不能分析那些动态页面

[ 本帖最后由 reiase 于 2008-8-16 12:15 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-07-09 14:45 |只看该作者
说实在的 这种程序除了炫耀外没多大意义

一个实际能用的上的爬虫要处理的东西很多的。。。

论坛徽章:
0
3 [报告]
发表于 2008-07-09 14:50 |只看该作者

回复 #2 cc007cc 的帖子

不是炫耀,我的目的看我签名

论坛徽章:
0
4 [报告]
发表于 2008-07-09 16:45 |只看该作者
贴出来大家共同学习呗,我自己写过一个下程序从网易抓新闻的。只不过都是用正则去匹配,没有HTMLParser

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

无语唉。

[ 本帖最后由 xiaoyu9805119 于 2008-7-9 16:47 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2008-07-09 17:24 |只看该作者
原帖由 xiaoyu9805119 于 2008-7-9 16:45 发表
贴出来大家共同学习呗,我自己写过一个下程序从网易抓新闻的。只不过都是用正则去匹配,没有HTMLParser

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

无语唉。


挂在服务器上

论坛徽章:
0
6 [报告]
发表于 2008-07-09 17:29 |只看该作者
程序有bug哦,没有对argv做parser

论坛徽章:
0
7 [报告]
发表于 2008-07-09 22:57 |只看该作者
原帖由 vuleetu 于 2008-7-9 17:29 发表
程序有bug哦,没有对argv做parser

我不会用argument的解析库

论坛徽章:
4
CU大牛徽章
日期:2013-03-13 15:29:07CU大牛徽章
日期:2013-03-13 15:29:49CU大牛徽章
日期:2013-03-13 15:30:192015亚冠之广州恒大
日期:2015-07-22 17:20:15
8 [报告]
发表于 2008-07-11 00:42 |只看该作者
我的建议是用正则 解析 HTMLParser 比起用正则 速度 相差大的 不信你可以去测试
你这个程序 我不说代码问题  

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

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

论坛徽章:
0
9 [报告]
发表于 2008-07-11 09:42 |只看该作者
原帖由 reiase 于 2008-7-9 14:06 发表
毕设时写的一个抓取图片url"类爬虫程序",这是第一个版本,第二个版本开线程开得太疯狂,有DDOS嫌疑,就不贴出来了。目前想添加cookie,javascript之类的功能进去
#!/usr/bin/python
from htmllib import *
...


感觉好乱。

论坛徽章:
0
10 [报告]
发表于 2008-07-11 10:06 |只看该作者
这个脚本只是抓去抓取连接,所以我说是类爬虫。具体用途是给一个学长写的程序提供输入。找了下,找到第二个版本了。第二个版本线程粒度更小,因此性能更好,缺点是在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库的段错误),就给放弃了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP