下载糗事百科的内容_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 11 Python
Python修改MP3文件的方法
Jun 15 Python
Python字符编码与函数的基本使用方法
Sep 30 Python
浅谈Series和DataFrame中的sort_index方法
Jun 07 Python
Centos 升级到python3后pip 无法使用的解决方法
Jun 12 Python
Python开发网站目录扫描器的实现
Feb 21 Python
pandas DataFrame创建方法的方式
Aug 02 Python
python批量处理文件或文件夹
Jul 28 Python
python脚本之一键移动自定格式文件方法实例
Sep 02 Python
Python udp网络程序实现发送、接收数据功能示例
Dec 09 Python
在Windows上安装和配置 Jupyter Lab 作为桌面级应用程序教程
Apr 22 Python
Python select及selectors模块概念用法详解
Jun 22 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 join函数应用
2011/05/04 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
自定义一个jquery插件[鼠标悬浮时候 出现说明label]
2011/06/27 Javascript
解决JQeury显示内容没有边距内容紧挨着浏览器边线
2013/12/20 Javascript
jQuery中attr()方法用法实例
2015/01/05 Javascript
纯js实现无限空间大小的本地存储
2015/06/18 Javascript
JS+CSS实现的日本门户网站经典选项卡导航效果
2015/09/27 Javascript
AngularJS入门教程之链接与图片模板详解
2016/08/19 Javascript
归纳下js面向对象的几种常见写法总结
2016/08/24 Javascript
移动端js图片查看器
2016/11/17 Javascript
AngularJS指令中的绑定策略实例分析
2016/12/14 Javascript
AngularJS实用基础知识_入门必备篇(推荐)
2017/07/10 Javascript
Vue学习笔记进阶篇之多元素及多组件过渡
2017/07/19 Javascript
webpack打包js的方法
2018/03/12 Javascript
vue-cli 组件的导入与使用教程详解
2018/04/11 Javascript
Angular6新特性之Angular Material
2018/12/28 Javascript
js计算最大公约数和最小公倍数代码实例
2019/09/11 Javascript
Vue中el-form标签中的自定义el-select下拉框标签功能
2020/04/20 Javascript
[01:14:05]《加油DOTA》第四期
2014/08/25 DOTA
[03:48]DOTA2完美大师赛主赛事第二日精彩集锦
2017/11/24 DOTA
[01:03:50]DOTA2-DPC中国联赛 正赛 CDEC vs DLG BO3 第二场 2月7日
2021/03/11 DOTA
[34:41]夜魇凡尔赛茶话会 第二期02:你画我猜
2021/03/11 DOTA
利用python程序生成word和PDF文档的方法
2017/02/14 Python
Django实现的自定义访问日志模块示例
2017/06/23 Python
Python3实战之爬虫抓取网易云音乐的热门评论
2017/10/09 Python
python pandas 对时间序列文件处理的实例
2018/06/22 Python
Python通过len函数返回对象长度
2020/10/22 Python
JackJones官方旗舰店:杰克琼斯男装
2018/03/27 全球购物
能否解释一下XSS cookie盗窃是什么意思
2012/06/02 面试题
旅游管理毕业生自荐书
2014/02/02 职场文书
社会学专业求职信
2014/02/24 职场文书
护理专业毕业生自我鉴定总结
2014/03/24 职场文书
副主任竞聘演讲稿
2014/08/18 职场文书
数学教师个人工作总结
2015/02/06 职场文书
Nginx使用X-Accel-Redirect实现静态文件下载的统计、鉴权、防盗链、限速等
2021/04/04 Servers
python调试工具Birdseye的使用教程
2021/05/25 Python