23hh小说网——爬虫python

  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'&nbsp;')
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和广告,速度也非常非常的慢;

于是自己就弄了这个一个爬虫,把所有小说章节从网页上爬下来。

看小说到我这种程度,算是苦逼了

原文地址:https://www.cnblogs.com/SilenceCity/p/3640395.html