python写采集程序_python实现简易采集爬虫
#!/usr/bin/python#-*-coding:utf-8-*-
#简易采集爬虫#1.采集Yahoo!Answers,parseData函数修改一下,可以采集任何网站#2.需要sqlite3或者pysqlite支持#3.可以在DreamHost.com空间上面运行#4.可以修改User-Agent冒充搜索引擎蜘蛛#5.可以设置暂停的时间,控制采集速度#6.采集Yahoo会被封IP数小时,所以这个采集用处不大#Author: Lukin#Date : 2008-09-25
#导入采集需要用到的模块
importre, sys, timeimporthttplib, os.path as ospfrom urlparse importurlparse#使用sqite数据库,为了兼容DreamHost.com的空间,只能这么写了
try:importsqlite3 as sqliteexceptImportError:from pysqlite2 importdbapi2 as sqlite#采集速度控制,单位秒
sleep =0#数据库路径
dbname = './database.db'
#设置提交的header头
headers = {"Accept": "*/*","Referer": "http://answers.yahoo.com/","User-Agent": "Mozilla/5.0+(compatible;+Googlebot/2.1;++http://www.google.com/bot.html)"}#连接服务器
dl = httplib.HTTPConnection('answers.yahoo.com')#连接数据库
conn =sqlite.connect(osp.abspath(dbname))#创建数据库
defcreateDatabase():globalconn,dbname;if osp.isfile(osp.abspath(dbname)) : returnc=conn.cursor()#创建url列表存放表
c.execute('''CREATE TABLE IF NOT EXISTS [collect]([cid] INTEGER PRIMARY KEY,[curl] TEXT,[state] INTEGER DEFAULT '0',UNIQUE([curl]));''')
c.execute('''CREATE INDEX IF NOT EXISTS [collect_idx_state] ON [collect]([state]);''')#创建分类表
c.execute('''CREATE TABLE IF NOT EXISTS [sorts]([sortid] INTEGER PRIMARY KEY,[sortname] TEXT,[sortpath] TEXT,[sortfoot] INTEGER DEFAULT '0',[sortnum] INTEGER DEFAULT '0',UNIQUE([sortpath]));''')
c.execute('''CREATE INDEX IF NOT EXISTS [sorts_idx_sortname] ON [sorts]([sortname]);''')
c.execute('''CREATE INDEX IF NOT EXISTS [sorts_idx_sortfoot] ON [sorts]([sortfoot]);''')#创建文章表
c.execute('''CREATE TABLE IF NOT EXISTS [article]([aid] INTEGER PRIMARY KEY,[sortid] INTEGER DEFAULT '0',[hits] INTEGER DEFAULT '0',[title] TEXT,[path] TEXT,[question] TEXT,[banswer] TEXT,[oanswer] TEXT,UNIQUE([path]));''')
c.execute('''CREATE INDEX IF NOT EXISTS [article_idx_sortid] ON [article]([sortid]);''')#事物提交
conn.commit()
c.close()#执行采集
def collect(url="http://answers.yahoo.com/"):global dl,error,headers; R =0print "GET:",url
urls= urlparse(url); path = urls[2];if urls[4]!='' : path += '?' + urls[4]
dl.request(method="GET", url=path, headers=headers); rs =dl.getresponse()if rs.status==200:
R=parseData(rs.read(),url);else:print "3 seconds, try again ..."; time.sleep(3)
dl.request(method="GET", url=path, headers=headers); rs =dl.getresponse()if rs.status==200:
R=parseData(rs.read(),url);else:print "3 seconds, try again ..."; time.sleep(3)
dl.request(method="GET", url=path, headers=headers); rs =dl.getresponse()if rs.status==200:
R=parseData(rs.read(),url);else:print "Continue to collect ..."R= 3
#更新记录
updateOneUrl(url,R)#返回结果
returnR#处理采集到的数据
defparseData(html,url):global dl,conn; R = 2;
c=conn.cursor()#格式化html代码
format =formatURL(clearBlank(html),url)#取出所有的连接
urls = re.findall(r'''(]*?href="([^"]+)"[^>]*?>)|(]*?href='([^']+)'[^>]*?>)''',format,re.I)if urls !=None :
i=0#循环所有的连接
for regs inurls :#得到一个单一的url
sUrl = en2chr(regs[1].strip())#判断url是否符合规则,符合,则插入数据库
if re.search('http(.*?)/(dir|question)/index(.*?)',sUrl,re.I) !=None :if re.search('http(.*?)/dir/index(.*?)',sUrl,re.I) !=None:if sUrl.find('link=list') == -1 and sUrl.find('link=over') == -1:
sUrl+= '&link=over'
else:
sUrl= sUrl.replace('link=list','link=over')if sUrl[-11:]=='link=mailto' : continue
try:
c.execute('INSERT INTO [collect]([curl])VALUES(?);',(sUrl,))
i= i + 1
exceptsqlite.IntegrityError :pass
if i>0 : print "Message: %d get a new URL." %(i,)#截取数据
if re.search('http(.*)/question/index(.*)',url,re.I) !=None :
sortfoot=0#自动创建分类和分类关系
guide = sect(format,'
- ','
','((.*?)Home(.*?))')
aGuide= re.findall(']*href="[^"]*"[^>]*>(.*?)',guide,re.I)if aGuide !=None :
sortname= ""
for sortname inaGuide :
sortname=sortname.strip()
sortpath=en2path(sortname)#查询分类是否存在
c.execute('SELECT [sortid],[sortname] FROM [sorts] WHERE [sortpath]=? LIMIT 0,1;',(sortpath,))
row=c.fetchone();#分类不存在,添加分类
if row==None :
c.execute('INSERT INTO [sorts]([sortname],[sortpath],[sortfoot])VALUES(?,?,?);',(sortname,sortpath,sortfoot))
sortfoot=c.lastrowidelse:
sortfoot=row[0]#标题
title = sect(format,'
','
')#最佳答案
BestAnswer = sect(format,'(
Best Answer(.*?)
(.*?)
)')#最佳答案不存在,则不采集
if BestAnswer !=None :#文章路径
path = en2path(sortname + '-' +title.strip())#问题
adddata = sect(format,'
')
content= sect(format,'(
(.*?)
)')if adddata != None : content += '
' +adddata#其他回答
OtherAnswer = ''
for regs in re.findall('
') == -1 and regs.find('
') == -1:
a1= sect(regs,'
')
a2= sect(regs,'
')
OtherAnswer+= '
'OtherAnswer+= '
'
#判断采集成功
if title != None and content !=None :#将数据写入到数据
try:
c.execute('INSERT INTO [article]([sortid],[title],[path],[question],[banswer],[oanswer])VALUES(?,?,?,?,?,?);',(sortfoot,title,path,content,BestAnswer,OtherAnswer))print "Message:%s.html" %(path,)
R= 1
exceptsqlite.IntegrityError :pass
#提交写入数据库
conn.commit(); c.close()returnR#取得一条URL
defgetOneUrl():global conn; c =conn.cursor()
c.execute('SELECT [curl] FROM [collect] WHERE [state] IN(0,3) LIMIT 0,1;')
row=c.fetchone(); c.close()if row==None : return ""
return row[0].encode('utf-8')#更新一条记录的状态
defupdateOneUrl(url,state):global conn; c =conn.cursor()
c.execute('UPDATE [collect] SET [state]=? WHERE [curl]=?;',(state,url))
conn.commit(); c.close()#清除html代码里的多余空格
defclearBlank(html):if len(html) == 0 : return ''html= re.sub('\r|\n|\t','',html)while html.find(" ")!=-1 or html.find(' ')!=-1:
html= html.replace(' ',' ').replace(' ',' ')returnhtml#格式化url
defformatURL(html,url):
urls= re.findall('''(]*?href="([^"]+)"[^>]*?>)|(]*?href='([^']+)'[^>]*?>)''',html,re.I)if urls == None : returnhtmlfor regs inurls :
html=html.replace(regs[0],matchURL(regs[0],url))returnhtml#格式化单个url
defmatchURL(tag,url):
urls= re.findall('''(.*)(src|href)=(.+?)( |/>|>).*|(.*)url\(([^\)]+)\)''',tag,re.I)if urls ==None :returntagelse:if urls[0][5] == '':
urlQuote= urls[0][2]else:
urlQuote= urls[0][5]if len(urlQuote) >0 :
cUrl= re.sub('''['"]''','',urlQuote)else:returntag
urls= urlparse(url); scheme =urls[0];if scheme!='' : scheme+='://'host= urls[1]; host = scheme +hostif len(host)==0 : returntag
path= osp.dirname(urls[2]);if path=='/' : path = '';if cUrl.find("#")!=-1 : cUrl = cUrl[:cUrl.find("#")]#判断类型
if re.search('''^(http|https|ftp):(//|\\\\)(([\w/\\\+\-~`@:%])+\.)+([\w/\\\.\=\?\+\-~`@':!%#]|(&)|&)+''',cUrl,re.I) !=None :#http开头的url类型要跳过
returntagelif cUrl[:1] == '/':#绝对路径
cUrl = host +cUrlelif cUrl[:3]=='../':#相对路径
while cUrl[:3]=='../':
cUrl= cUrl[3:]if len(path) >0 :
path=osp.dirname(path)elif cUrl[:2]=='./':
cUrl= host + path + cUrl[1:]elif cUrl.lower()[:7]=='mailto:' or cUrl.lower()[:11]=='javascript:':returntagelse:
cUrl= host + path + '/' +cUrl
R= tag.replace(urlQuote,'"' + cUrl + '"')returnR#html代码截取函数
def sect(html,start,end,cls=''):if len(html)==0 : return;#正则表达式截取
if start[:1]==chr(40) and start[-1:]==chr(41) and end[:1]==chr(40) and end[-1:]==chr(41) :
reHTML= re.search(start + '(.*?)' +end,html,re.I)if reHTML == None : returnreHTML=reHTML.group()
intStart=re.search(start,reHTML,re.I).end()
intEnd=re.search(end,reHTML,re.I).start()
R=reHTML[intStart:intEnd]#字符串截取
else:#取得开始字符串的位置
intStart =html.lower().find(start.lower())#如果搜索不到开始字符串,则直接返回空
if intStart == -1 : return
#取得结束字符串的位置
intEnd = html[intStart+len(start):].lower().find(end.lower())#如果搜索不到结束字符串,也返回为空
if intEnd == -1 : return
#开始和结束字符串都有了,可以开始截取了
R = html[intStart+len(start):intStart+intEnd+len(start)]#清理内容
if cls != '':
R=clear(R,cls)#返回截取的字符
returnR#正则清除
defclear(html,regexs):if regexs == '' : returnhtmlfor regex in regexs.split(chr(10)):
regex=regex.strip()if regex != '':if regex[:1]==chr(40) and regex[-1:]==chr(41):
html= re.sub(regex,'',html,re.I|re.S)else:
html= html.replace(regex,'')returnhtml#格式化为路径
defen2path(enStr):return re.sub('[\W]+','-',en2chr(enStr),re.I|re.U).strip('-')#替换实体为正常字符
defen2chr(enStr):return enStr.replace('&','&')#------------------------------------- 开始执行程序 -------------------------------------------
#首先创建数据库
createDatabase()#开始采集
loops =0whileTrue:if loops>0 :
url=getOneUrl()if url == "":
loops=0else:
loops=collect(url)else:
loops=collect()#暂停
time.sleep(sleep)if loops==0 : break
#关闭HTTP连接
dl.close()#退出程序
sys.exit()
python写采集程序_python实现简易采集爬虫相关推荐
- python写窗体程序_python写窗口
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 最近在学习 pyqt5 gui 编程,大致路线是找了套网课<撩课-pyth ...
- 用python写秒杀程序_Python 实现淘宝秒杀的示例代码
新手学习Python,之前在网上看见一位朋友写的40行Python代码搞定京东秒杀,想在淘宝上帮女朋友抢玩偶,所以就照猫画虎的写了下淘宝的秒杀脚本,经自己实验可行.直接上代码: #-*- coding ...
- python 写cs程序_Python cs.cmdutils包_程序模块 - PyPI - Python中文网
版本20190729: BaseCommand:支持usage_format usage消息格式字符串和getopt_error_处理程序方法. 类BaseCommand 用于处理可嵌套命令行的基类. ...
- python写新年快乐程序_python turtle 书写新年快乐
农历2018年的最后一篇文章,踏上回家的征途前,推荐一个 Python 的三方库 turtle ,是一个可以绘制图像文字的库. 这里的例子比较简单,就是依据各个点坐标连线最后形成文字的,先附上成品图的 ...
- 快速掌握用python写并行程序
目录 一.大数据时代的现状 二.面对挑战的方法 2.1 并行计算 2.2 改用GPU处理计算密集型程序 3.3 分布式计算 三.用python写并行程序 3.1 进程与线程 3.2 全局解释器锁GIL ...
- python如何在没有环境的电脑上执行_没安装python的电脑可以运行python写的程序吗 python语言编写的程...
py2exe 能够把 Python script 转换成可以在windows上独立执行的(即不需安装Python)的exe程序(加上其它必需的运行时函数库). -- 摘自百度知道 py2exe能够把P ...
- 用Python写表白程序,给另一半一个惊喜
每年的七夕或者情人节,基本送的都是玫瑰花或者小礼物,送多了,也就没有了什么惊喜,今天教大家一个用Python写表白程序的办法,给你的另一半一个惊喜. 用python实现表白程序的方法: 1.创建GUI ...
- 用python写一个程序
用python写个程序 1.概述 计算机程序(Computer program) 是指一组指示计算机或其他具有处理能力装置每一步动作的指令,通常用于程序设计的语言编写 .能够写python的程序有很多 ...
- 手把手教你使用python写提取快捷酒店房间信息的采集程序
自从过完年之后没有发过什么文章了,一直在写一个快捷酒店房间采集程序,现在已经做完了七天连锁的和如家的房间信息采集,现在会陆续将代码贴上来 我的python工程的目录如下图所示: 程序是使用python ...
最新文章
- 20年资深Oracle数据库专家:国内应用级DBA的缺失
- 【js笔记】数组那些事[0]
- Win32 汇编环境和入门程序图解
- Oracle 表空间数据文件迁移图解
- python网络爬虫的论文模板_Python简单网络爬虫实战—下载论文名称,作者信息(上)...
- 【设计模式】——工厂方法FactoryMethod
- acwing提高组 第一章 动态规划
- 《C++ Primer 5th》笔记(4 / 19):表达式
- LeetCode 206 Reverse Linked List 解题报告
- PHP安装ZIP扩展
- php system 返回值126,exec – PHP return_val是126
- 高等组合学笔记(九): 球盒模型的十二模式,分拆的生成函数
- CTS(2)---CTS、CTS-V、GTS版本更新,及其注意事项
- c语言 对排两个答案文件
- java c 语言之父_Java之父评价C语言之父:我用尽了形容词
- 2015-5-23PDF的下载链接
- Android 进阶——系统启动之核心SystemServer进程启动详解(七)
- 两个程序的爱情故事(刘欣)
- azw3格式的电子书在kindle中怎么打开
- gta5结局杀老崔我哭了_GTA5:玩家眼中的重情义,剧情中变定时炸弹,崔佛为何是个疯子?...
热门文章
- 打印菱形图案用java如何做_Java打印出菱形图案
- Android集成微信支付之-天坑
- 把服务器sql数据库导出excel文件,将mysql数据库数据以Excel文件的形式导出
- 利用python进行数据分析(四)
- win10下用VMware workstation pro安装Ubuntu 16.04图解
- LaTex如何自动生成参考文献
- NOIP2003 侦探推理 详解
- 一键清理电脑垃圾文件
- 200 OK (from cache) 与 304 Not Modified
- Java项目:宠物医院预约管理系统设计和实现(java+springboot+mysql+ssm)