下载糗事百科的内容_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 相关文章推荐
运用TensorFlow进行简单实现线性回归、梯度下降示例
Mar 05 Python
Python Pandas找到缺失值的位置方法
Apr 12 Python
python实现超市扫码仪计费
May 30 Python
Python面向对象类的继承实例详解
Jun 27 Python
Python 实现Windows开机运行某软件的方法
Oct 14 Python
python生成每日报表数据(Excel)并邮件发送的实例
Feb 03 Python
Python Web框架之Django框架Model基础详解
Aug 16 Python
django-rest-swagger对API接口注释的方法
Aug 29 Python
python爬虫爬取笔趣网小说网站过程图解
Nov 18 Python
Python3 selenium 实现QQ群接龙自动化功能
Apr 17 Python
python中strip(),lstrip(),rstrip()函数的使用讲解
Nov 17 Python
python pandas 解析(读取、写入)CSV 文件的操作方法
Dec 24 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判断并删除空目录及空子目录的方法
2015/02/11 PHP
php实现读取和写入tab分割的文件
2015/06/01 PHP
如何解决phpmyadmin导入数据库文件最大限制2048KB
2015/10/09 PHP
mac下多个php版本快速切换的方法
2016/10/09 PHP
php中序列化与反序列化详解
2017/02/13 PHP
PHP长连接实现与使用方法详解
2018/02/11 PHP
Yii框架实现对数据库的CURD操作示例
2019/09/03 PHP
在VS2008中使用jQuery智能感应的方法
2010/12/30 Javascript
Array, Array Constructor, for in loop, typeof, instanceOf
2011/09/13 Javascript
jQuery中width()方法用法实例
2014/12/24 Javascript
jQuery插件Slider Revolution实现响应动画滑动图片切换效果
2015/06/05 Javascript
基于Jquery实现表单验证
2020/07/20 Javascript
JS实现仿新浪微博发布内容为空时提示功能代码
2015/08/19 Javascript
几种二级联动案例(jQuery\Array\Ajax php)
2016/08/13 Javascript
arcgis for js 修改infowindow样式的方法
2016/11/02 Javascript
原生JS+Canvas实现五子棋游戏
2020/05/28 Javascript
AngularJS实现的2048小游戏功能【附源码下载】
2018/01/03 Javascript
Element-ui table中过滤条件变更表格内容的方法
2018/03/02 Javascript
详解webpack4多入口、多页面项目构建案例
2018/05/25 Javascript
iview实现select tree树形下拉框的示例代码
2018/12/21 Javascript
nodejs基础之多进程实例详解
2018/12/27 NodeJs
JavaScript键盘事件响应顺序详解
2019/09/30 Javascript
Javascript幻灯片播放功能实现过程解析
2020/05/07 Javascript
vant中的toast层级改变操作
2020/11/04 Javascript
简单介绍Python中的几种数据类型
2016/01/02 Python
用Python实现最速下降法求极值的方法
2019/07/10 Python
python中property属性的介绍及其应用详解
2019/08/29 Python
django框架基于queryset和双下划线的跨表查询操作详解
2019/12/11 Python
python百行代码自制电脑端网速悬浮窗的实现
2020/05/12 Python
CSS3实现点击放大的动画实例代码
2017/02/27 HTML / CSS
耐克中国官方商城:Nike中国
2018/10/18 全球购物
请假条格式范文
2014/04/10 职场文书
廉政承诺书范文
2015/04/28 职场文书
工会经费申请报告
2015/05/15 职场文书
Pytorch 如何实现LSTM时间序列预测
2021/05/17 Python
多人盗宝《绿林侠盗》第三赛季4.5上线 跨平台实装
2022/04/03 其他游戏