下载糗事百科的内容_python版


Posted in Python onDecember 07, 2008
#coding:utf-8 import urllib.request 
import xml.dom.minidom 
import sqlite3 
import threading 
import time 
class logger(object): 
def log(self,*msg): 
for i in msg: 
print(i) 
Log = logger() 
Log.log('测试下') 
class downloader(object): 
def __init__(self,url): 
self.url = url 
def download(self): 
Log.log('开始下载',self.url) 
try: 
content = urllib.request.urlopen(self.url).read() 
#req = urllib.request.Request(url) 
#response = urllib.request.urlopen(req) 
#content = response.read() 
Log.log('下载完毕') 
return(content) 
except: 
Log.log('下载出错') 
return(None) 

class parser(object): 
def __init__(self,content): 
#获得根节点 
self.html = xml.dom.minidom.parseString(content) 
def parse(self): 
Log.log('开始提取数据') 
contents = {'content':'','url':[]} 
#获得div节点 
divs = self.html.getElementsByTagName('div') 
#获得content节点 
for div in divs: 
if div.hasAttribute('class') and \ 
div.getAttribute('class') == 'content': 
#获得糗事百科的内容 
textNode = div.childNodes[0] 
qContent = textNode.data 
#数据填充 
contents['content'] = qContent 
#获得上一糗事、下一糗事节点 
spans = self.html.getElementsByTagName('span') 
for span in spans: 
pspan = span.parentNode 
if pspan.tagName == 'a': 
#pspan为对应的链接,此时需要将对应的地址加入数据库 
url = pspan.getAttribute('href') 
qid = url[10:][:-4] 
#数据填充 
contents['url'].append(qid) 
Log.log('提取数据完毕') 
return(contents) 
def downloadPage(qid,db): 
url = 'http://www.qiushibaike.com/articles/'+str(qid)+'.htm' 
content = downloader(url).download() 
if content: 
contents = parser(content).parse() 
if contents['content']: 
db.updateContent(qid,contents['content']) 
for i in contents['url']: 
db.addQID(i) 
if len(contents['url']) == 2: 
db.updateStatus(qid,2) 
#下载池,表示同时允许下载的链接个数 
class downloaderPool(object): 
def __init__(self,maxLength=15): 
self.downloaders = [None]*maxLength 
self.downloadList = [] 
self.db = None 
def setDownloadList(self,downloadList): 
self.downloadList = list(set(self.downloadList+downloadList)) 
def setdb(self,db): 
self.db = db 
def daemon(self): 
#每隔一秒查询线程的状态,为非活动线程则设置为None 
Log.log('设置守护进程') 
for index,downloader in enumerate(self.downloaders): 
if downloader: 
if not downloader.isAlive(): 
Log.log('将下载器置空',index) 
self.downloaders[index] = None 
#检查线程池状态 
for index,downloader in enumerate(self.downloaders): 
if not downloader: 
qid = self.getQID() 
if qid: 
#创建线程 
t = threading.Thread(target=downloadPage,args=(qid,self.db)) 
self.downloaders[index] = t 
t.start() 
t.join() 
Log.log('设置下载器',index) 
#间隔一秒执行一次 
time.sleep(1) 
def getQID(self): 
try: 
tmp = self.downloadList[0] 
del self.downloadList[0] 
return(tmp) 
except: 
return(None) 
def beginDownload(self): 
#创建守护线程 
daemon = threading.Thread(target=self.daemon) 
daemon.setDaemon(True) 
daemon.start() 
daemon.join() 
def getDownloader(self): 
for index,downloader in enumerate(self.downloaders): 
if not downloader: 
return(index) 
return(None) 

ADD_Q_ID = 'insert into qiushibaike(id,success) values(?,?)' 
UPDATE_Q_CONTENT = 'update qiushibaike set content=? where id=?' 
UPDATE_Q_STATUS = 'update qiushibaike set success=? where id=?' 
Q_LIST = 'select id from qiushibaike where success=?' 
Q_LIST_BY_ID = 'select count(*) from qiushibaike where id=?' 
class dbConnect(object): 
""" 
create table qiushibaike( 
id,Integer 
content,Varchar 
success,Interger 
) 
#id表示糗事的ID 
#content表示糗事的内容 
#success表示是否下载成功,当该糗事内容下载完成,且获得上一页、下一页ID时表示下载完成 
1表示未完成 
2表示完成 
""" 
def __init__(self,dbpath='db.sqlite'): 
self.dbpath = dbpath 
def addQID(self,qid): 
Log.log('插入糗事百科',qid) 
#获得连接 
cn = sqlite3.connect(self.dbpath) 
c = cn.cursor() 
try: 
#添加内容并提交 
c.execute(ADD_Q_ID,(qid,1)) 
cn.commit() 
except: 
Log.log('添加ID出错',qid) 
#关闭连接 
c.close() 
cn.close() 
Log.log('插入成功') 
def updateContent(self,qid,content): 
Log.log('更新糗事百科',qid,content) 
#获得连接 
cn = sqlite3.connect(self.dbpath) 
c = cn.cursor() 
#添加内容并提交 
c.execute(UPDATE_Q_CONTENT,(content,qid)) 
cn.commit() 
#关闭连接 
c.close() 
cn.close() 
Log.log('更新成功') 
def updateStatus(self,qid,flag): 
Log.log('更新状态',qid,flag) 
#获得连接 
cn = sqlite3.connect(self.dbpath) 
c = cn.cursor() 
#添加内容并提交 
c.execute(UPDATE_Q_STATUS,(flag,qid)) 
cn.commit() 
#关闭连接 
c.close() 
cn.close() 
Log.log('更新状态成功') 
def getList(self,unDonloaded=1): 
Log.log('获得列表') 
l = [] 
#获得连接 
cn = sqlite3.connect(self.dbpath) 
c = cn.cursor() 
#获得数据 
c.execute(Q_LIST,(unDonloaded,)) 
rows = c.fetchall() 
for i in rows: 
l.append(i[0]) 
#关闭连接 
c.close() 
cn.close() 
Log.log('获得列表成功') 
return(l) 
class singleDownloader(object): 
def __init__(self): 
self.downloadList = [] 
def setdb(self,db): 
self.db = db 
def setDownloadList(self,downloadList): 
self.downloadList = list(set(self.downloadList+downloadList)) 
def beginDownload(self): 
for i in self.downloadList: 
downloadPage(i,self.db) 
def main(): 
db = dbConnect('db.sqlite') 
#dp = downloaderPool() 
#dp.setdb(db) 
sp = singleDownloader() 
sp.setdb(db) 
dp=sp 
unDownloadedList = db.getList() 
#当还有未下载的糗事时就要继续下载 
while(len(unDownloadedList)): 
#使用该列表填充下载池 
dp.setDownloadList(unDownloadedList) 
dp.beginDownload() 
time.sleep(1) 
#重置参数 
unDownloadedList = db.getList() 
if __name__ == '__main__': 
main()

代码是没问题的,可以正常运行,但是希望做到以下2方面:
1、多线程下载
2、代码分离度更高,跟面向对象
Python 相关文章推荐
实例讲解python函数式编程
Jun 09 Python
Python简单连接MongoDB数据库的方法
Mar 15 Python
windows下python安装paramiko模块和pycrypto模块(简单三步)
Jul 06 Python
快速入门python学习笔记
Dec 06 Python
python调用系统ffmpeg实现视频截图、http发送
Mar 06 Python
详解python分布式进程
Oct 08 Python
详解利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击
Oct 09 Python
PyQt5使用QTimer实现电子时钟
Jul 29 Python
Python如何实现小程序 无限求和平均
Feb 18 Python
python logging模块的使用
Sep 07 Python
Python3+Appium安装及Appium模拟微信登录方法详解
Feb 16 Python
Python超简单容易上手的画图工具库推荐
May 10 Python
python 参数列表中的self 显式不等于冗余
Dec 01 #Python
Python GAE、Django导出Excel的方法
Nov 24 #Python
Python类的基础入门知识
Nov 24 #Python
Python 连连看连接算法
Nov 22 #Python
python sqlobject(mysql)中文乱码解决方法
Nov 14 #Python
Python转码问题的解决方法
Oct 07 #Python
Python函数学习笔记
Oct 07 #Python
You might like
PHP form 表单传参明细研究
2009/07/17 PHP
Base64在线编码解码实现代码 演示与下载
2011/01/08 PHP
判断php数组是否为索引数组的实现方法
2013/06/13 PHP
如何使用纯PHP实现定时器任务(Timer)
2015/07/31 PHP
深入浅析php json 格式控制
2015/12/24 PHP
windows下的WAMP环境搭建图文教程(推荐)
2017/07/27 PHP
PHP实现链式操作的三种方法详解
2017/11/16 PHP
javascript函数库-集合框架
2007/04/27 Javascript
javascript中的变量是传值还是传址的?
2010/04/19 Javascript
向左滚动文字 js代码效果
2013/08/17 Javascript
Jquery中children与find之间的区别详细解析
2013/11/29 Javascript
遮罩层点击按钮弹出并且具有拖动和关闭效果(两种方法)
2015/08/20 Javascript
微信小程序 详解Page中data数据操作和函数调用
2017/01/12 Javascript
基于bootstrap实现收缩导航条
2017/03/17 Javascript
基于ES6 Array.of的用法(实例讲解)
2017/09/05 Javascript
移动端效果之IndexList详解
2017/10/20 Javascript
webpack+vue中使用别名路径引用静态图片地址
2017/11/20 Javascript
浅谈Webpack 持久化缓存实践
2018/03/22 Javascript
js实现QQ邮箱邮件拖拽删除功能
2020/08/27 Javascript
vue 动态生成拓扑图的示例
2021/01/03 Vue.js
python的三目运算符和not in运算符使用示例
2014/03/03 Python
Django的数据模型访问多对多键值的方法
2015/07/21 Python
python实现多线程的方式及多条命令并发执行
2016/06/07 Python
Python 使用with上下文实现计时功能
2018/03/09 Python
详解Python中的内建函数,可迭代对象,迭代器
2019/04/29 Python
Win10 安装PyCharm2019.1.1(图文教程)
2019/09/29 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
2020/06/18 Python
纯HTML5+CSS3制作生日蛋糕代码
2016/11/16 HTML / CSS
大学毕业的自我鉴定
2013/10/08 职场文书
创伤外科专业推荐信范文
2013/11/19 职场文书
编辑硕士自荐信范文
2013/11/27 职场文书
寒假思想汇报
2014/01/10 职场文书
面试自我评价范文
2014/09/17 职场文书
2014乡镇机关党员个人对照检查材料思想汇报
2014/10/09 职场文书
幼儿园小班工作总结2015
2015/04/25 职场文书
毕业欢送会致辞
2015/07/29 职场文书