运维进行时
热衷于开源技术,一起学习,共同进步。
首页
开源项目
每日酷Shell
招聘专栏
标签
留言
边栏
归档
星标日志
RSS
写一个爬虫程序[原创]
刘天斯
, 2010/03/08 10:33 ,
Python
,
评论(3)
,
阅读(3960)
, Via 本站原创
大
|
中
|
小
引用地址:
注意:
该地址仅在今日23:59:59之前有效
写爬虫是一项复杂、枯噪、反复的工作,考虑的问题包括采集效率、链路异常处理、数据质量(与站点编码规范关系很大)等。整理自己写一个爬虫程序,单台服务器可以启用1~8个实例同时采集,然后将数据入库。
#-*- coding:utf-8 -*- #!/usr/local/bin/python import sys, time, os,string import mechanize import urlparse from BeautifulSoup import BeautifulSoup import re import MySQLdb import logging import cgi from optparse import OptionParser #----------------------------------------------------------------------------# # Name: TySpider.py # # Purpose: WebSite Spider Module # # Author: 刘天斯 # # Email: liutiansi@gamil.com # # Created: 2010/02/16 # # Copyright: (c) 2010 # #----------------------------------------------------------------------------# """ |-------------------------------------------------------------------------- | 定义 loging class; |-------------------------------------------------------------------------- | | 功能:记录系统相关日志信息。 | | """ class Pubclilog(): def __init__(self): self.logfile = 'website_log.txt' def iniLog(self): logger = logging.getLogger() filehandler = logging.FileHandler(self.logfile) streamhandler = logging.StreamHandler() fmt = logging.Formatter('%(asctime)s, %(funcName)s, %(message)s') logger.setLevel(logging.DEBUG) logger.addHandler(filehandler) logger.addHandler(streamhandler) return [logger,filehandler] """ |-------------------------------------------------------------------------- | 定义 tySpider class; |-------------------------------------------------------------------------- | | 功能:抓取分类、标题等信息 | | """ class BaseTySpider: #初始化相关成员方法 def __init__(self,X,log_switch): #数据库连接 self.conn = MySQLdb.connect(db='dbname',host='192.168.0.10', user='dbuser',passwd='SDFlkj934y5jsdgfjh435',charset='utf8') #分类及标题页面Community self.CLASS_URL = 'http://test.abc.com/aa/CommTopicsPage?' #发表回复页 self.Content_URL = 'http://test.bac.com/aa/CommMsgsPage?' #开始comm值 self.X=X #当前comm id取模,方面平均到表 self.mod=self.X%5 #Community文件下载页 self.body="" #self.bodySoup对象 self.soup=None #发表回复页下载内容变量 self.Contentbody="" #发表回复页内容self.ContentbodySoup对象 self.Contentsoup=None #日志开关 self.log_switch=log_switch #======================获取名称及分类方法========================== def _SpiderClass(self,nextpage=None): if nextpage==None: FIXED_QUERY = 'cmm='+str(self.X) else: FIXED_QUERY = nextpage[1:] try: rd = mechanize.Browser() rd.addheaders = [("User-agent", "Tianya/2010 (compatible; MSIE 6.0;Windows NT 5.1)")] rd.open(self.CLASS_URL + FIXED_QUERY) self.body=rd.response().read() #rd=mechanize.Request(self.CLASS_URL + FIXED_QUERY) #response = mechanize.urlopen(rd) #self.body=response.read() except Exception,e: if self.log_switch=="on": logapp=Pubclilog() logger,hdlr = logapp.iniLog() logger.info(self.CLASS_URL + FIXED_QUERY+str(e)) hdlr.flush() logger.removeHandler(hdlr) return self.soup = BeautifulSoup(self.body) NextPageObj= self.soup("a", {'class' : re.compile("fs-paging-item fs-paging-next")}) self.cursor = self.conn.cursor() if nextpage==None: try: Ttag=str(self.soup.table) #print Ttag """ ------------------分析结构体-----------------
Dunhill
中国
»
人民
""" soupTable=BeautifulSoup(Ttag) #定位到第一个h1标签 tableh1 = soupTable("h1") #print self.X #print "Name:"+tableh1[0].string.strip().encode('utf-8') #处理无类型的 try: #定位到表格中符合规则“^TopByCategory”A链接块,tablea[0]为第一个符合条件的连接文字,tablea[1]... tablea = soupTable("a", {'href' : re.compile("^TopByCategory")}) if tablea[0].string.strip()=="": pass #print "BigCLass:"+tablea[0].string.strip().encode('utf-8') #print "SubClass:"+tablea[1].string.strip().encode('utf-8') except Exception,e: if self.log_switch=="on": logapp=Pubclilog() logger,hdlr = logapp.iniLog() logger.info("[noClassInfo]"+str(self.X)+str(e)) hdlr.flush() logger.removeHandler(hdlr) self.cursor.execute("insert into baname"+str(self.mod)+" values('%d','%d','%s')" %(self.X,-1,tableh1[0].string.strip().encode('utf-8'))) self.conn.commit() self._SpiderTitle() if NextPageObj: NextPageURL=NextPageObj[0]['href'] self._SpiderClass(NextPageURL) return else: return #获取链接二对象的href值 classlink=tablea[1]['href'] par_dict=cgi.parse_qs(urlparse.urlparse(classlink).query) #print "CID:"+par_dict["cid"][0] #print "SubCID:"+par_dict["subcid"][0] #print "---------------------------------------" #插入数据库 self.cursor.execute("insert into class values('%d','%s')" %(int(par_dict["cid"][0]),tablea[0].string.strip().encode('utf-8'))) self.cursor.execute("insert into subclass values('%d','%d','%s')" %(int(par_dict["subcid"][0]),int(par_dict["cid"][0]),tablea[1].string.strip().encode('utf-8'))) self.cursor.execute("insert into baname"+str(self.mod)+" values('%d','%d','%s')" %(self.X,int(par_dict["subcid"][0]),tableh1[0].string.strip().encode('utf-8'))) self.conn.commit() self._SpiderTitle() if NextPageObj: NextPageURL=NextPageObj[0]['href'] self._SpiderClass(NextPageURL) self.body=None self.soup=None Ttag=None soupTable=None table=None table1=None classlink=None par_dict=None except Exception,e: if self.log_switch=="on": logapp=Pubclilog() logger,hdlr = logapp.iniLog() logger.info("[ClassInfo]"+str(self.X)+str(e)) hdlr.flush() logger.removeHandler(hdlr) else: self._SpiderTitle() if NextPageObj: NextPageURL=NextPageObj[0]['href'] self._SpiderClass(NextPageURL) #====================获取标题方法========================= def _SpiderTitle(self): #查找标题表格对象(table) soupTitleTable=self.soup("table", {'class' : "fs-topic-list"}) #查找标题行对象(tr) TitleTr = soupTitleTable[0]("tr", {'onmouseover' : re.compile("^this\.className='fs-row-hover'")}) """ -----------分析结构体--------------
【新人报到】欢迎美国人民加入
0 /
12
中国人
2-14
""" for CurrTr in TitleTr: try: #初始化置顶及精华状态 Title_starred='N' Title_sticky='N' #获取当前记录的BeautifulSoup对象 soupCurrTr=BeautifulSoup(str(CurrTr)) #BeautifulSoup分析HTML有误,只能通过span的标志数来获取贴子状态,会存在一定误差 #如只有精华时也会当成置顶来处理。 TitleStatus=soupCurrTr("span", {'title' : ""}) TitlePhotoViewer=soupCurrTr("a", {'href' : re.compile("^PhotoViewer")}) if TitlePhotoViewer.__len__()==1: TitlePhotoViewerBool=0 else: TitlePhotoViewerBool=1 if TitleStatus.__len__()==3-TitlePhotoViewerBool: Title_starred='Y' Title_sticky='Y' elif TitleStatus.__len__()==2-TitlePhotoViewerBool: Title_sticky='Y' #获取贴子标题 Title=soupCurrTr.a.next.strip() #获取贴子ID par_dict=cgi.parse_qs(urlparse.urlparse(soupCurrTr.a['href']).query) #获取回复数及浏览器 TitleNum=soupCurrTr("td", {'class' : "fs-topic-name"}) TitleArray=string.split(str(TitleNum[0]),'\n') Title_ReplyNum=string.split(TitleArray[len(TitleArray)-4],'>')[2] Title_ViewNum=string.split(TitleArray[len(TitleArray)-2],'>')[2][:-6] #获取贴子作者 TitleAuthorObj=soupCurrTr("td", {'style' : "padding-left:4px"}) Title_Author=TitleAuthorObj[0].next.next.next.string.strip().encode('utf-8') #获取回复时间 TitleTime=soupCurrTr("td", {'class' : re.compile("^fs-topic-last-mdfy fs-meta")}) """ print "X:"+str(self.X) print "Title_starred:"+Title_starred print "Title_sticky:"+Title_sticky print "Title:"+Title #获取贴子内容连接URL print "Title_link:"+soupCurrTr.a['href'] print "CID:"+par_dict["tid"][0] print "Title_ReplyNum:"+Title_ReplyNum print "Title_ViewNum:"+Title_ViewNum print "Title_Author:"+Title_Author print "TitleTime:"+TitleTime[0].string.strip().encode('utf-8') """ #入库 self.cursor.execute("insert into Title"+str(self.mod)+" values('%s','%d','%s','%d','%d','%s','%s','%s','%s')" %(par_dict["tid"][0], \ self.X,Title,int(Title_ReplyNum),int(Title_ViewNum),Title_starred,Title_sticky, \ Title_Author.decode('utf-8'),TitleTime[0].string.strip().encode('utf-8'))) self.conn.commit() self._SpiderContent(par_dict["tid"][0]) except Exception,e: if self.log_switch=="on": logapp=Pubclilog() logger,hdlr = logapp.iniLog() logger.info("[Title]"+str(self.X)+'-'+par_dict["tid"][0]+'-'+str(e)) hdlr.flush() logger.removeHandler(hdlr) #======================获取发表及回复方法======================= def _SpiderContent(self,ID,nextpage=None): if nextpage==None: FIXED_QUERY = 'cmm='+str(self.X)+'&tid='+ID+'&ref=regulartopics' else: FIXED_QUERY = nextpage[9:] rd = mechanize.Browser() rd.addheaders = [("User-agent", "Tianya/2010 (compatible; MSIE 6.0;Windows NT 5.1)")] rd.open(self.Content_URL + FIXED_QUERY) self.Contentbody=rd.response().read() #rd=mechanize.Request(self.Content_URL + FIXED_QUERY) #response = mechanize.urlopen(rd) #self.Contentbody=response.read() self.Contentsoup = BeautifulSoup(self.Contentbody) NextPageObj= self.Contentsoup("a", {'class' : re.compile("fs-paging-item fs-paging-next")}) try: Tdiv=self.Contentsoup("div", {'class' : "fs-user-action"}) i=0 for Currdiv in Tdiv: if i==0: Ctype='Y' else: Ctype='N' #发表时间 soupCurrdiv=BeautifulSoup(str(Currdiv)) PosttimeObj=soupCurrdiv("span", {'class' : "fs-meta"}) Posttime=PosttimeObj[0].next[1:] Posttime=Posttime[0:-3] #IP地址 IPObj=soupCurrdiv("a", {'href' : re.compile("CommMsgAddress")}) if IPObj: IP=IPObj[0].next.strip() else: IP='' #发表/回复内容 ContentObj=soupCurrdiv("div", {'class' :"fs-user-action-body"}) Content=ContentObj[0].renderContents().strip() """ print "ID:"+str(self.X) print "ID:"+ID print "Ctype:"+Ctype print "POSTTIME:"+Posttime print "IP:"+IP print "Content:"+Content """ self.cursor.execute("insert into Content"+str(self.mod)+" values('%s','%d','%s','%s','%s','%s')" %(ID,self.X,Ctype,Posttime,IP,Content.decode('utf-8'))) self.conn.commit() i+=1 except Exception,e: if self.log_switch=="on": logapp=Pubclilog() logger,hdlr = logapp.iniLog() logger.info("[Content]"+str(self.X)+'-'+ID+'-'+str(e)) hdlr.flush() logger.removeHandler(hdlr) #如“下一页”有链接刚继续遍历 if NextPageObj: NextPageURL=NextPageObj[0]['href'] self._SpiderContent(ID,NextPageURL) def __del__(self): try: self.cursor.close() self.conn.close() except Exception,e: pass #遍历comm范围 def initapp(StartValue,EndValue,log_switch): for x in range(StartValue,EndValue): app=BaseTySpider(x,log_switch) app._SpiderClass() app=None if __name__ == "__main__": #定义命令行参数 MSG_USAGE = "TySpider.py [ -s StartNumber EndNumber ] -l [on|off] [-v][-h]" parser = OptionParser(MSG_USAGE) parser.add_option("-s", "--set", nargs=2,action="store", dest="comm_value", type="int", default=False, help="配置名称ID值范围。".decode('utf-8')) parser.add_option("-l", "--log", action="store", dest="log_switch", type="string", default="on", help="错误日志开关".decode('utf-8')) parser.add_option("-v","--version", action="store_true", dest="verbose", help="显示版本信息".decode('utf-8')) opts, args = parser.parse_args() if opts.comm_value: if opts.comm_value[0]>opts.comm_value[1]: print "终止值比起始值还小?" exit(); if opts.log_switch=="on": log_switch="on" else: log_switch="off" initapp(opts.comm_value[0],opts.comm_value[1],log_switch) exit(); if opts.verbose: print "WebSite Scider V1.0 beta." exit;
如大家有什么疑问或感兴趣的话题可以通过weibo与我交流:
http://t.qq.com/yorkoliu
Tags:
爬虫
,
python
服务器管理系统-手机终端
服务器管理系统服务器端D
scoke
2011/03/15 22:55
谢谢,已经解决了,是eclipse不能导入python模块导致的。
scoke
2011/03/15 21:56
还是不太明白,安装的模块如下
root@scoke-v:/usr/local/lib/python2.6/dist-packages# ls
easy-install.pth mechanize-0.2.4-py2.6.egg
该如何写才不会出错,谢谢这么快的回复
scoke
2011/03/15 17:56
你好,我在引用mechanize模块的时候
import mechanize
br = mechanize.Browser()
使用eclipse调试的时候报错如下
Traceback (most recent call last):
File "/root/python/python/1.py", line 3, in <module>
import mechanize
File "/root/python/python/mechanize.py", line 4, in <module>
AttributeError: 'module' object has no attribute 'Browser'
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'mechanize']
不过在终端执行这个语句又是正常的。python是2.6,很是迷惑,可以解答一下吗?谢谢
刘天斯
回复于 2011/03/15 18:38
注意文件名与系统模块同名。
分页: 1/1
1
发表评论
昵称
网址
电邮
打开HTML
打开UBB
打开表情
隐藏
记住我
[登入]
[注册]
个人简介
姓名:刘天斯
BLOG:
http://blog.liuts.com
TX微博
:
http://t.qq.com/yorkoliu
工作经历:
1、天涯社区(2005~2011)
2、腾讯(2011~今)
职务:架构师、系统管理员
籍贯:海南琼海
Email、MSN:
技术交流QQ群:
106651609[1号] 满
106651547[2号] 满
37654606[3号] 满
8672312[4号] 满
158926355[5号]
203734755[资深]
分类
默认分类
[0]
Linux
[46]
Architecture
[1]
SA
[2]
rrdtool
[1]
Windows
[2]
Ubuntu
[10]
MYSQL
[17]
SQLSERVER
[1]
Memcached
[2]
MongoDB
[2]
LVS
[4]
DNS
[6]
Apache
[8]
Lighttpd
[3]
Resin
[1]
Haproxy
[2]
Squid
[1]
Varnish
[3]
Nginx
[2]
SHELL
[14]
JAVA
[4]
C/C++
[7]
PHP
[11]
Python
[35]
Perl
[2]
Ajax
[3]
CSS
[2]
Javascript
[6]
Adode
[2]
MooseFS
[3]
Cfengine
[2]
Splunk
[1]
Func
[6]
Qmail/Postfix
[2]
RSA
[3]
Hardware/Network
[1]
TOOL/Software
[0]
My Life
[10]
日历
<
2012
>
<
2
>
壬辰年(龙)
日
一
二
三
四
五
六
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
最新日志
一例千万级pv高性能高并...
祝贺《构建高可用Linu...
RedBridge: R...
告别天涯,加盟腾讯
童真[原创]
常见负载均衡器禁(启)用...
技能大赛评委记[原创]
51CTO专访记录[原创...
彤彤一周岁记
基于Keepalived...
最新评论
老刘这个很霸道哦
问题找到了,由于测试环境...
您好,请问我按照您的方式...
众多开源技术的集合,牛呀...
望天斯兄根据此图出书,就...
这本书真的值得推荐吗?书...
妈呀,看完了,惊讶死我了...
谢谢分享经验......
这个网站配置文件的字符编...
天斯,请问你这个图是用什...
第二个支持的了
依然的支持了,呵呵
刘兄, 我想问一下 如何...
请问下,我按照大师做出来...
大牛,想请问一下按照你的...
我觉得高技术的人都挺厉害...
那就支持了,呵呵
拜读了刘天斯兄的文章谢谢...
能发给我我么
这样比较麻烦噢。配置几台...
No module ex...
您好, 网页显示rrdt...
刘兄我想问一下根据你上面...
天斯。我想在cfengi...
我的nginx+uwsg...
喜欢集群技术,支持这本书...
确认一下你的版本及定义的...
在cfagent.con...
#cfrun cfrun...
#cfrun cfrun...
可惜迟到了,不过还是留痕...
路过,这是做什么的呢?
刘兄你好,请问Serve...
抢个位置。
刘哥:我执行func命令...
您好: 我现在的情况是这...
很幸福的一家
mode http 和m...
Starting cer...
小孩子就是讨人爱!
天涯有什么不好?还是恭喜...
这个工具很强啊 学习了
呃。。看不大懂啊。。好深
各有各的好吧
yum -y insta...
Thank blogge...
天哥去TX了,难怪开通会...
你好:你这里的从服务器和...
你说的同步指得是什么?
从服务器配置和主服务器配...
没钱去啊
你好 ,我安装完slav...
很专业的知识,有点深奥。...
祝福天斯。
补充一点:Nginx报5...
好久不见,没想到你去腾讯...
前程似锦!加油!
你到腾讯哪个部门?我也在...
祝刘兄一切顺利
公司ip,极可能高于4个...
祝天斯前程似锦,跟你学到...
祝福一切顺利!
腾讯大厦离我们这里不远啊
刘大哥,那个监控hapr...
祝福天斯老兄!
祝福老大。
ImageMagick ...
祝福刘老大,在你的blo...
不错哇,,,恭喜恭喜~
天斯去深圳了,还是来北京...
祝天斯兄顺利!
支持你~ 天斯哥! 订阅...
企鹅的平台伸展空间还是很...
订阅你博客很长时间了,期...
invalid requ...
你好,请问func0.2...
这原创详细啊。。 给力
我碰到个问题,查了很多资...
我以前也很迷protot...
我也用RockMongo...
链接
同事好友
蒙其·B·宾森的博客
嘻嘻9_9 BLOG
Sam in Tianya
粗苶淡饭
Vimer的程序世界
IT好友
BMForum
回忆未来[张宴]
Jean – 记录成长历程
鱼常游而忘飞
dba blog
恋上E人
网海过客
unixhot
灰太狼的blog
抚琴煮酒
selboo's blog
懒人运维
K.I.S.S. – 简单哲学
badb0y's blog
young for you
ThinkSOA
IT工地
晓辉工作室
Queryer
tickecho老吴
康盛博客
story的天空
英才and栋梁'S Blog
疯子的视界
雨林木风-高进波
ISADBA|FH.CN
老万-不知所谓
Vi`blog
linxun's blog
运维人生
kindle's blog
e2fsck's blog
Phoenix的实验室
SYSTEMADMIN
安静的角落!
专注linux领域
Sudu's Blog
Laird-SA
鹧鸪天BLOG
darkmi'blog
运维日志
阿熊的窝
未来往事
陋室博客
51运维管理社区
青年怪客
叶茂盛
Pw
飛飛's Blog
开源项目
天涯LVS管理系统
天涯服务器管理系统(C/S版)
天涯服务器管理系统(手机版)
在线图片处理平台
服务器机柜模拟图平台
SDR-Linux主机集中管理
Varnish缓存推送平台V1.0
网址收藏
SED单行脚本快速参考
C++ 标准库
python在线命令行
Python资源索引
htaccess在线生成
在线检查HTTP HEAD
有奖积分小游戏
python代码搜索引擎
php作者之PHP Performance
Google AdSense
CSS-BUTTON
在线绘图
doit时间管理
python模块集中营
归档
2012/02
2012/01
2011/12
2011/11
2011/10
其他
登入
注册
申请链接
RSS:
日志
|
评论
编码:UTF-8
XHTML 1.0
订阅本站
访客来源
root@scoke-v:/usr/local/lib/python2.6/dist-packages# ls
easy-install.pth mechanize-0.2.4-py2.6.egg
该如何写才不会出错,谢谢这么快的回复
import mechanize
br = mechanize.Browser()
使用eclipse调试的时候报错如下
Traceback (most recent call last):
File "/root/python/python/1.py", line 3, in <module>
import mechanize
File "/root/python/python/mechanize.py", line 4, in <module>
AttributeError: 'module' object has no attribute 'Browser'
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'mechanize']
不过在终端执行这个语句又是正常的。python是2.6,很是迷惑,可以解答一下吗?谢谢