运维进行时
互联网运维与架构
首页
开源项目
书籍纠错汇总
招聘专栏
标签
留言
边栏
归档
星标日志
RSS
写一个爬虫程序[原创]
刘天斯
, 2010/03/08 10:33 ,
Python
,
评论(3)
,
阅读(35247)
, 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
微博
:
http://t.qq.com/yorkoliu
http://weibo.com/yorkoliu
工作经历:
1、天涯社区(2005~2011)
2、腾讯(2011~今)
职务:架构师、高级系统工程师
发明专利:
7
个
籍贯:海南琼海
Email、MSN:
个人著作:
技术交流QQ群:
106651609[1号] 满
106651547[2号] 满
37654606[3号] 满
8672312[4号] 满
158926355[5号] 满
251989396[6号]
203734755[资深]
分类
默认分类
[3]
BigData
[3]
Docker
[4]
Linux
[44]
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
[39]
saltstack
[1]
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
[11]
我的著作
[1]
日历
<
2024
>
<
12
>
日
一
二
三
四
五
六
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
30
31
最新日志
参与定制行业标准-《数据...
大数据资产管理在腾讯游戏...
专家视野 | ...
腾讯游戏大数据解密:De...
从天涯到腾讯:10年,不...
基于Django与Cel...
基于kubernetes...
《python自动化运维...
《python自动化运维...
《Python自动化运维...
最新评论
你写得非常清晰明了,让我...
代码错误实在太多,git...
k10s, ])求救,这...
高大上
如此好文章一定要留下名啊
虽然不知道说的是什么,但...
我买了,这本书有没有网页...
查询google的A记录...
# haproxy co...
ERROR : conn...
数据库内容是怎么样操作是...
不错不错,好久没更新了。
运行出错No hosts...
不错,很好
使用后台命令行没什么问题...
# No minions...
天斯兄,我操作的时候总是...
天斯兄,有3个问题。1,...
一直很欣赏博主
请问新版 什么时候出 有...
--- no pytho...
现在的案例源码到哪里可以...
docker-py与RE...
选择好服务器执行返回结果...
File /usr/li...
博主,你好,我运行etc...
膜拜高人,都出书啦!佩服
好神器!正需要管理几千台...
在专利网站上搜索你的名字...
连不上数据库。。。
人生最难得的是一份坚持啊...
新版本用不了了!,环境如...
我想说的是我一台dock...
每篇都是雄文哈
好久没逛过天涯了。
Thu Jul 21 1...
现在的案例源码到哪里可以...
请问查看etcd节点,是...
老大的这些图用什么画的?
进来看看、支持一下
你好,在 go 脚本文件...
赞
Traceback (m...
OMserver页面中的...
saltstack201...
本人买了您的写的书,对于...
启动services后,...
感觉关于lvs的有点乱,...
利用celery可以实现...
似乎缺少一个docker...
我准备安装这个服务,但在...
请问天斯,目前Hapro...
6.3.2 案例:实现堡...
请问你的拓扑图是用什么软...
有没有详细的安装教程,安...
吐槽一下你的书,上周刚买...
谢谢分享哦!
写的真好!
好文哦,赞一个!
请问您的架构图 是用什么...
django-debug...
细节没讲清楚.菜鸟按这流...
接上:在librarie...
saltstack执行命...
刘老师,现在报No mo...
刘老师,按照上述说明配置...
你好,最近在测试kube...
# source pro...
有没有电子版?
好文!前段时间刚搞定这块...
刘天斯,你这个网站是用什...
我想知道 在运行pyth...
OMserver页面中的...
LZ的书我买了,我觉得s...
直接复制你的json,用...
直接复制你的json,用...
天斯哥,打扰了,最近在使...
# vi Makefil...
scriptalert(...
大师,想了解一下你的个人...
链接
同事好友
蒙其·B·宾森的博客
嘻嘻9_9 BLOG
Sam in Tianya
粗苶淡饭
Vimer的程序世界
chauvet's blog
MinUnix系统运维
Nornor's Blog
系统运维
幽龙博客
黑光技术
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
Virtual World
centos中文站
未来往事
IT自学网
峰云,就她了。
linux菜园子
51运维网
Linux中国
tshare365
Dig All Possible
应用性能管理
吴光科-京峰Linux运维培训
开源项目
天涯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模块集中营
归档
2024/12
2024/11
2024/10
2024/09
2024/08
其他
登入
注册
申请链接
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,很是迷惑,可以解答一下吗?谢谢