Python 爬虫 之 阅读呼叫转移(三)

    虽然上一篇博客中我们可以连续地阅读章节了,但是,难道每一次看小说都运行一下我们的 Python 程序?连记录看到哪里都不行,每次都是重新来过?当然不能这样,改!现在这么多小说阅读器,我们只需要把我们要的小说抓取到本地的 txt 文件里就好了,然后自己选个阅读器看,怎么整都看你了。


    其实上个程序我们已经完成了大部分逻辑,我们接下来的改动只需要把抓取到每一章的时候不用显示出来,而是存入 txt 文件之中。另外一个是程序是不断地根据下一页的 Url 进行抓取的,那么什么时候结束呢?注意当到达小说的最后一章时下一页的链接是和返回目录的链接是一样的。所以我们抓取一个网页的时候就把这两个链接拿出来,只要出现两个链接一样的时候,就停止抓取。最后就是我们这个程序不需要多线程了,我们只要一个不断在抓取小说页面的线程就行了。

    不过,小说章节多一点时候,等待完成的时间会有点久。目前就不考虑这么多了,基本功能完成就 OK....


    基础知识:前面的基础知识 - 多线程知识 + 文件操作知识。


     源代码:

# -*- coding:utf-8 -*-

import urllib2
import urllib
import re
import thread
import chardet

class Book_Spider:

    def __init__(self):
        self.pages = []
        self.page = 1
        self.flag = True
        self.url = "http://www.quanben.com/xiaoshuo/0/910/59302.html"

    # 将抓取一个章节
    def GetPage(self):
        myUrl = self.url
        user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
        headers = { 'User-Agent' : user_agent }
        req = urllib2.Request(myUrl, headers = headers)
        myResponse = urllib2.urlopen(req)
        myPage = myResponse.read()

        charset = chardet.detect(myPage)
        charset = charset['encoding']
        if charset == 'utf-8' or charset == 'UTF-8':
            myPage = myPage
        else:
            myPage = myPage.decode('gb2312','ignore').encode('utf-8')
        unicodePage = myPage.decode("utf-8")

        # 找出 id="content"的div标记
        try:
            #抓取标题
            my_title = re.search('<h1>(.*?)</h1>',unicodePage,re.S)
            my_title = my_title.group(1)
        except:
            print '标题 HTML 变化,请重新分析!'
            return False
        
        try:
            #抓取章节内容
            my_content = re.search('<div.*?id="htmlContent" class="contentbox">(.*?)<div',unicodePage,re.S)
            my_content = my_content.group(1)
        except:
            print "内容 HTML 变化,请重新分析!"
            return False
        
        my_content = my_content.replace("<br />","\n")
        my_content = my_content.replace(" "," ")

        #用字典存储一章的标题和内容
        onePage = {'title':my_title,'content':my_content}

        try:
            #找到页面下方的连接区域
            foot_link = re.search('<div.*?class="chapter_Turnpage">(.*?)</div>',unicodePage,re.S)
            foot_link = foot_link.group(1)
            #在连接的区域找下一页的连接,根据网页特点为第三个
            nextUrl = re.findall(u'<a.*?href="(.*?)".*?>(.*?)</a>',foot_link,re.S)
            #目录链接
            dir_url = nextUrl[1][0]
            nextUrl = nextUrl[2][0]
            # 更新下一次进行抓取的链接
            self.url = nextUrl

            if(dir_url == nextUrl):
                self.flag = False
                
            return onePage
        except:
            print "底部链接变化,请重新分析!"
            return False

    # 用于加载章节
    def downloadPage(self):

        f_txt = open(u"斗罗大陆.txt",'w+')
        while self.flag:
            try:
                # 获取新的页面
                myPage = self.GetPage()
                
                if myPage == False:
                        print '抓取失败!'
                        self.flag = False

                title = myPage['title'].encode('utf-8')
                content = myPage['content'].encode('utf-8')

                f_txt.write(title + '\n\n')
                f_txt.write(content)
                f_txt.write('\n\n\n')

                print "已下载 ",myPage['title']

            except:
                print '无法连接服务器!'
                self.flag = False
                
        f_txt.close()

    def Start(self):
        print u'开始下载......\n'

        self.downloadPage()


        print u"下载完成"


#----------- 程序的入口处 -----------
print u"""
---------------------------------------
   程序:阅读呼叫转移
   版本:0.3
   作者:angryrookie
   日期:2014-07-08
   语言:Python 2.7
   功能:按下回车开始下载
---------------------------------------
"""

print u'请按下回车:'
raw_input(' ')
myBook = Book_Spider()
myBook.Start()




    效果见图:


你可能感兴趣的:(爬虫,python,文件操作,阅读,阅读器)