下载糗事百科的内容_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 相关文章推荐
python3中dict(字典)的使用方法示例
Mar 22 Python
django rest framework之请求与响应(详解)
Nov 06 Python
Python简单实现查找一个字符串中最长不重复子串的方法
Mar 26 Python
详解Python下ftp上传文件linux服务器
Jun 21 Python
python控制nao机器人身体动作实例详解
Apr 29 Python
Django集成搜索引擎Elasticserach的方法示例
Jun 04 Python
python Shapely使用指南详解
Feb 18 Python
Python 实现日志同时输出到屏幕和文件
Feb 19 Python
PySide2出现“ImportError: DLL load failed: 找不到指定的模块”的问题及解决方法
Jun 10 Python
python集合的新增元素方法整理
Dec 07 Python
如何用 Python 处理不平衡数据集
Jan 04 Python
Python 中的Sympy详细使用
Aug 07 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数组中删除元素的实现代码
2012/06/22 PHP
php模拟用户自动在qq空间发表文章的方法
2015/01/07 PHP
php获取'/'传参的值简单方法
2017/07/13 PHP
PHP实现的登录页面信息提示功能示例
2017/07/24 PHP
iphone safari不支持position fixed的解决方法
2012/05/04 Javascript
DOM节点删除函数removeChild()用法实例
2015/01/12 Javascript
jQuery图片左右滚动代码 有左右按钮实例
2016/06/20 Javascript
jQuery Easyui学习教程之实现datagrid在没有数据时显示相关提示内容
2016/07/09 Javascript
Javascript OOP之面向对象
2016/07/31 Javascript
基于原生JS实现图片裁剪
2016/08/01 Javascript
AngularJS入门教程之表单校验用法示例
2016/11/02 Javascript
vue 2.0封装model组件的方法
2017/08/03 Javascript
在一般处理程序(ashx)中弹出js提示语
2017/08/16 Javascript
JavaScript编写的网页小游戏,很给力
2017/08/18 Javascript
Bootstrap实现翻页效果
2017/11/27 Javascript
JQuery事件委托原理与用法实例分析
2019/05/13 jQuery
基于javascript处理nginx请求过程详解
2020/07/07 Javascript
Python中isnumeric()方法的使用简介
2015/05/19 Python
Python requests发送post请求的一些疑点
2018/05/20 Python
django 多数据库配置教程
2018/05/30 Python
python打包生成的exe文件运行时提示缺少模块的解决方法
2018/10/31 Python
Python装饰器使用你可能不知道的几种姿势
2019/10/25 Python
解决pytorch报错:AssertionError: Invalid device id的问题
2020/01/10 Python
python实现超级玛丽游戏
2020/03/18 Python
keras使用Sequence类调用大规模数据集进行训练的实现
2020/06/22 Python
Maxpeedingrods美国:高性能汽车零件
2020/02/14 全球购物
学生实习自我鉴定
2013/10/11 职场文书
婚礼主持词
2014/03/13 职场文书
承诺书的格式范文
2014/03/28 职场文书
说好普通话圆梦你我他演讲稿
2014/09/21 职场文书
民间借贷协议书范本
2014/10/01 职场文书
党员学习群众路线心得体会
2014/11/04 职场文书
小学二年级数学教学计划
2015/01/20 职场文书
2016年小学优秀班主任事迹材料
2016/02/29 职场文书
漫画《催眠麦克风-Dawn Of Divisions》第二卷PV公开
2022/04/05 日漫
解决flex布局中子项目尺寸不受flex-shrink限制
2022/05/11 HTML / CSS