#!/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,'

  1. ','

','((.*?)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('

(.+?)

',format):if regs.find('

') == -1 and regs.find('

') == -1:

a1= sect(regs,'

','

')

a2= sect(regs,'

','

')

OtherAnswer+= '

' +a1if a2 != None : OtherAnswer+= '

' + a2 + '

'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实现简易采集爬虫相关推荐

  1. python写窗体程序_python写窗口

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 最近在学习 pyqt5 gui 编程,大致路线是找了套网课<撩课-pyth ...

  2. 用python写秒杀程序_Python 实现淘宝秒杀的示例代码

    新手学习Python,之前在网上看见一位朋友写的40行Python代码搞定京东秒杀,想在淘宝上帮女朋友抢玩偶,所以就照猫画虎的写了下淘宝的秒杀脚本,经自己实验可行.直接上代码: #-*- coding ...

  3. python 写cs程序_Python cs.cmdutils包_程序模块 - PyPI - Python中文网

    版本20190729: BaseCommand:支持usage_format usage消息格式字符串和getopt_error_处理程序方法. 类BaseCommand 用于处理可嵌套命令行的基类. ...

  4. python写新年快乐程序_python turtle 书写新年快乐

    农历2018年的最后一篇文章,踏上回家的征途前,推荐一个 Python 的三方库 turtle ,是一个可以绘制图像文字的库. 这里的例子比较简单,就是依据各个点坐标连线最后形成文字的,先附上成品图的 ...

  5. 快速掌握用python写并行程序

    目录 一.大数据时代的现状 二.面对挑战的方法 2.1 并行计算 2.2 改用GPU处理计算密集型程序 3.3 分布式计算 三.用python写并行程序 3.1 进程与线程 3.2 全局解释器锁GIL ...

  6. python如何在没有环境的电脑上执行_没安装python的电脑可以运行python写的程序吗 python语言编写的程...

    py2exe 能够把 Python script 转换成可以在windows上独立执行的(即不需安装Python)的exe程序(加上其它必需的运行时函数库). -- 摘自百度知道 py2exe能够把P ...

  7. 用Python写表白程序,给另一半一个惊喜

    每年的七夕或者情人节,基本送的都是玫瑰花或者小礼物,送多了,也就没有了什么惊喜,今天教大家一个用Python写表白程序的办法,给你的另一半一个惊喜. 用python实现表白程序的方法: 1.创建GUI ...

  8. 用python写一个程序

    用python写个程序 1.概述 计算机程序(Computer program) 是指一组指示计算机或其他具有处理能力装置每一步动作的指令,通常用于程序设计的语言编写 .能够写python的程序有很多 ...

  9. 手把手教你使用python写提取快捷酒店房间信息的采集程序

    自从过完年之后没有发过什么文章了,一直在写一个快捷酒店房间采集程序,现在已经做完了七天连锁的和如家的房间信息采集,现在会陆续将代码贴上来 我的python工程的目录如下图所示: 程序是使用python ...

最新文章

  1. 20年资深Oracle数据库专家:国内应用级DBA的缺失
  2. 【js笔记】数组那些事[0]
  3. Win32 汇编环境和入门程序图解
  4. Oracle 表空间数据文件迁移图解
  5. python网络爬虫的论文模板_Python简单网络爬虫实战—下载论文名称,作者信息(上)...
  6. 【设计模式】——工厂方法FactoryMethod
  7. acwing提高组 第一章 动态规划
  8. 《C++ Primer 5th》笔记(4 / 19):表达式
  9. LeetCode 206 Reverse Linked List 解题报告
  10. PHP安装ZIP扩展
  11. php system 返回值126,exec – PHP return_val是126
  12. 高等组合学笔记(九): 球盒模型的十二模式,分拆的生成函数
  13. CTS(2)---CTS、CTS-V、GTS版本更新,及其注意事项
  14. c语言 对排两个答案文件
  15. java c 语言之父_Java之父评价C语言之父:我用尽了形容词
  16. 2015-5-23PDF的下载链接
  17. Android 进阶——系统启动之核心SystemServer进程启动详解(七)
  18. 两个程序的爱情故事(刘欣)
  19. azw3格式的电子书在kindle中怎么打开
  20. gta5结局杀老崔我哭了_GTA5:玩家眼中的重情义,剧情中变定时炸弹,崔佛为何是个疯子?...

热门文章

  1. 打印菱形图案用java如何做_Java打印出菱形图案
  2. Android集成微信支付之-天坑
  3. 把服务器sql数据库导出excel文件,将mysql数据库数据以Excel文件的形式导出
  4. 利用python进行数据分析(四)
  5. win10下用VMware workstation pro安装Ubuntu 16.04图解
  6. LaTex如何自动生成参考文献
  7. NOIP2003 侦探推理 详解
  8. 一键清理电脑垃圾文件
  9. 200 OK (from cache) 与 304 Not Modified
  10. Java项目:宠物医院预约管理系统设计和实现(java+springboot+mysql+ssm)