下载糗事百科的内容_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系列之从文件读取和保存数据
May 23 Python
深入解析Python编程中super关键字的用法
Jun 24 Python
python模拟登录并且保持cookie的方法详解
Apr 04 Python
python dataframe常见操作方法:实现取行、列、切片、统计特征值
Jun 09 Python
tensorflow 输出权重到csv或txt的实例
Jun 14 Python
使用 Python 处理3万多条数据只要几秒钟
Jan 19 Python
appium+python adb常用命令分享
Mar 06 Python
pytorch查看通道数 维数 尺寸大小方式
May 26 Python
python全栈开发语法总结
Nov 22 Python
pyspark对Mysql数据库进行读写的实现
Dec 30 Python
python Scrapy爬虫框架的使用
Jan 21 Python
python学习之panda数据分析核心支持库
May 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实现的下载css文件中的图片的代码
2010/02/08 PHP
自定义session存储机制避免会话保持问题
2014/10/08 PHP
Laravel的Auth验证Token验证使用自定义Redis的例子
2019/09/30 PHP
laravel框架使用极光推送消息操作示例
2020/02/15 PHP
如何在node的express中使用socket.io
2014/12/15 Javascript
JavaScript获取一个范围内日期的方法
2015/04/24 Javascript
JavaScript匿名函数之模仿块级作用域
2015/12/12 Javascript
Angularjs注入拦截器实现Loading效果
2015/12/28 Javascript
Angular中$compile源码分析
2016/01/28 Javascript
浅谈JS中json数据的处理
2016/06/30 Javascript
JavaScript 继承详解(五)
2016/10/11 Javascript
详解webpack异步加载业务模块
2017/06/23 Javascript
JS实现发送短信验证后按钮倒计时功能(防止刷新倒计时失效)
2017/07/07 Javascript
微信小程序开发之animation循环动画实现的让云朵飘效果
2017/07/14 Javascript
引入JavaScript时alert弹出框显示中文乱码问题
2017/09/16 Javascript
Angular项目从新建、打包到nginx部署全过程记录
2017/12/09 Javascript
vuex actions传递多参数的处理方法
2018/09/18 Javascript
Vue组件之单向数据流的解决方法
2018/11/10 Javascript
uni-app之APP和小程序微信授权方法
2019/05/09 Javascript
微信小程序tabBar 返回tabBar不刷新页面
2019/07/25 Javascript
微信小程序实现图片翻转效果的实例代码
2019/09/20 Javascript
vue-cli3中配置alias和打包加hash值操作
2020/09/04 Javascript
angular8.5集成TinyMce5的使用和详细配置(推荐)
2020/11/16 Javascript
Python使用metaclass实现Singleton模式的方法
2015/05/05 Python
PyQt5实现从主窗口打开子窗口的方法
2019/06/19 Python
解决pyqt5中QToolButton无法使用的问题
2019/06/21 Python
Django框架静态文件使用/中间件/禁用ip功能实例详解
2019/07/22 Python
基于Python的Jenkins的二次开发操作
2020/05/12 Python
利用CSS3伪元素实现逐渐发光的方格边框
2017/05/07 HTML / CSS
canvas绘制树形结构可视图形的实现
2020/04/03 HTML / CSS
美国婚礼礼品网站:MyWeddingFavors
2018/09/26 全球购物
学生手册家长评语
2014/02/10 职场文书
给学校的建议书范文
2014/05/15 职场文书
机关作风建设心得体会
2014/10/22 职场文书
2015年高二班主任工作总结
2015/05/25 职场文书
一小时迅速入门Mybatis之bind与多数据源支持 Java API
2021/09/15 Javascript