1 #! /bin/python 2 # -*- coding:utf-8 -*- 3 4 # -------------------------------------------- 5 # 程序:【23hh小说网】爬虫 6 # 版本:0.2 7 # 作者:Silence 8 # 日期:2014-04-01 9 # 操作:输入quit 10 # 功能:提供一个目录页,把这个小说的全部章节都抓取下来 11 # --------------------------------------------- 12 import urllib2 13 import re 14 import os 15 16 class Novel_Tool: 17 18 def __init__(self,weburl): 19 self.url = weburl 20 self.headers = { 21 'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6' 22 } 23 24 self.pagesInfo = {} 25 26 #获取当前页面的编码格式,现在某些小说网喜欢用gbk来编码 27 # 但是,也有一些不厚道的网站,他们的实际编码格式不是在页面中charset中定义的格式,暂时先忽略了 28 def getPageType(self,content): 29 pattern = re.compile('charset=.*?"') 30 pagetype = pattern.search(content).group() 31 pagetype = pagetype[8:len(pagetype) - 1] 32 return pagetype 33 34 def start(self): 35 # 得到utf-8编码的小说返回文本 36 req = urllib2.Request( 37 url = self.url, 38 headers = self.headers 39 ) 40 myResponse = urllib2.urlopen(req).read() 41 # print myResponse 42 decodeResp = myResponse.decode(self.getPageType(myResponse)).encode('utf-8') 43 44 pagesInfo = self.getAllUrlsAndNames(decodeResp) 45 # index = 1 46 for index,pageInfo in pagesInfo.items(): 47 # print page 48 print '正在爬第%d个页面……'%index 49 req = urllib2.Request( 50 url = pageInfo['pageurl'], 51 headers = self.headers 52 ) 53 print pageInfo['pageurl'] 54 pageResponse = urllib2.urlopen(req).read() 55 decodePageResp = pageResponse.decode(self.getPageType(pageResponse)).encode('utf-8') 56 pageContent = self.getPageContent(decodePageResp) 57 self.writeToFile(pageContent,pageInfo['pagename']) 58 59 def writeToFile(self,content,filename): 60 if os.path.exists(os.getcwd() + '/Nodels'): 61 if not os.path.isdir(os.getcwd() + '/Nodels'): 62 os.rename('Nodels','Nodels.bak') 63 os.mkdir(os.getcwd() + '/Nodels') 64 else: 65 os.mkdir(os.getcwd() + '/Nodels') 66 67 ofile = open(os.getcwd() + '/Nodels/' + filename,'w') 68 print os.getcwd() + '/Nodels/' + filename 69 try: 70 ofile.write(content) 71 except Exception, e: 72 print '存储网页',filename,'出错!' 73 finally: 74 ofile.close() 75 76 def getPageContent(self,content): 77 contentPattern = re.compile('(<dd id="contents">)((.|s)*?)(</dd>)') 78 content = contentPattern.search(content).group(2) 79 content = self.replaceWebTag(content) 80 return content 81 82 # 获取下一页的地址 83 def getNextPage(self,content): 84 # 先获取到下一页的位置 85 footlinkRex = re.compile('(footlink">)(.*?)</dd>') 86 foot = footlinkRex.search(content).group(2) 87 pattern = re.compile(r'(返回目录.*?(<a.*?">下一页))') 88 m = pattern.search(foot).groups() 89 nextUrl = m[len(m)-1][9:m[len(m)-1].find('">')] 90 91 return self.url[0:self.url.rfind('/')+1] + nextUrl 92 93 def getAllUrlsAndNames(self,content): 94 print '正在分析目录页面,请稍后…………' 95 pageRex = re.compile('<a href=".*?</td>') #定义获取所有章节页面链接的正则 96 pageUrlRex = re.compile('".*?"') #获取章节url的正则 97 pageNameRex = re.compile('>.*?<') #获取章节名字的正则 98 99 pages = pageRex.findall(content) 100 index = 1 101 for page in pages: 102 pageurl = pageUrlRex.search(page).group() 103 pageurl = pageurl[1:len(pageurl) - 1] 104 pageurl = self.url + pageurl 105 106 pagename = pageNameRex.search(page).group() 107 pagename = pagename[1:len(pagename) - 1] 108 109 # print pagename + ' ' + pageurl 110 self.pagesInfo[index] = { 111 'pagename' : pagename, 112 'pageurl' : pageurl 113 } 114 index = index + 1 115 print '目录页分析完成!该小说共有%d个章节'%index 116 return self.pagesInfo 117 118 119 def getNovelName(self,content): 120 titleRex = re.compile('<h1>.*?</h1>') 121 title = titleRex.search(content).group() 122 return title[4:len(title) - 5] 123 124 def replaceWebTag(self,content): 125 charToNoneRex = re.compile(r' ') 126 charToNewLineRex = re.compile("<br />|<br>|<br/>") 127 128 content = charToNoneRex.sub("",content) 129 content = charToNewLineRex.sub(" ",content) 130 return content 131 132 if __name__ == '__main__': 133 print u""" 134 # -------------------------------------------- 135 # 程序:【23hh小说网】爬虫 136 # 版本:0.2 137 # 作者:Silence 138 # 日期:2014-04-01 139 # 操作:启动后输入要爬得小说目录页地址,就可以自动爬了 140 # 功能:提供一个目录页,把目录页中所有的目录章节都抓出来(默认是:23hh的争霸天下), 141 # 分章节保存在启动脚本目录下的Novels目录下;如果该目录下已经有一个Novels,则把这个Novels改名为Novels.bak 142 # ---------------------------------------------""" 143 144 myinput = raw_input('请输入要爬的小说目录页面地址(默认是:23hh的争霸天下) ') 145 if myinput == '': 146 myinput = 'http://www.23hh.com/book/43/43957/' 147 nodel = Novel_Tool(myinput) 148 nodel.start()
周末自己看小说,发现现在的网页上,一次请求回来的东西有很多无用的js和广告,速度也非常非常的慢;
于是自己就弄了这个一个爬虫,把所有小说章节从网页上爬下来。
看小说到我这种程度,算是苦逼了