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

一篇博客我们成功地从网页上爬下了小说的一个章节,理所当然地,接下来我们要把整本小说都爬下来。首先,我们要把程序从原来的读完一章就结束,改成读完一章之后可以继续进行下一章的阅读。

    注意到每个小说章节的网页下面都有下一页的链接。通过查看网页源代码,稍微整理一下(  不显示了),我们可以看到这一部分的 HTML 是下面这种格式的:

[html]  view plain copy
  1. <div id="footlink">  
  2.   <script type="text/javascript" charset="utf-8" src="/scripts/style5.js"></script>  
  3.   <a href="http://www.quanben.com/xiaoshuo/0/910/59301.html">上一页</a>      
  4.   <a href="http://www.quanben.com/xiaoshuo/0/910/">返回目录</a>      
  5.   <a href="http://www.quanben.com/xiaoshuo/0/910/59303.html">下一页</a>  
  6. </div>  

     上一页  返回目录 下一页 都在一个 id 为 footlink  的 div 中,如果想要对每个链接进行匹配的话,会抓取到网页上大量的其他链接,但是 footlink 的 div 只有一个啊!我们可以把这个 div 匹配到,抓下来,然后在这个抓下来的 div  里面再匹配 <a> 的链接,这时就只有三个了。只要取最后一个链接就是下一页的 url 的,用这个 url 更新我们抓取的目标 url ,这样就能一直抓到下一页。用户阅读逻辑为每读一个章节后,等待用户输入,如果是 quit 则退出程序,否则显示下一章。


     基础知识:

     上一篇的基础知识加上 Python 的 thread 模块.


     源代码:

[python]  view plain copy
  1. # -*- coding: utf-8 -*-  
  2.   
  3. import urllib2  
  4. import re  
  5. import thread  
  6. import chardet  
  7.   
  8. class Book_Spider:  
  9.   
  10.     def __init__(self):  
  11.         self.pages = []  
  12.         self.page = 1  
  13.         self.flag = True  
  14.         self.url = "http://www.quanben.com/xiaoshuo/10/10412/2095096.html"  
  15.   
  16.     # 将抓取一个章节  
  17.     def GetPage(self):  
  18.         myUrl = self.url  
  19.         user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'  
  20.         headers = { 'User-Agent' : user_agent }  
  21.         req = urllib2.Request(myUrl, headers = headers)  
  22.         myResponse = urllib2.urlopen(req)  
  23.         myPage = myResponse.read()  
  24.   
  25.         charset = chardet.detect(myPage)  
  26.         charset = charset['encoding']  
  27.         if charset == 'utf-8' or charset == 'UTF-8':  
  28.             myPage = myPage  
  29.         else:  
  30.             myPage = myPage.decode('gb2312','ignore').encode('utf-8')  
  31.         unicodePage = myPage.decode("utf-8")  
  32.   
  33.         # 找出 id="content"的div标记  
  34.         #抓取标题  
  35.         my_title = re.search('<div.*?id="title"><h1>(.*?)</h1></div>',unicodePage,re.S)  
  36.         my_title = my_title.group(1)  
  37.         #抓取章节内容  
  38.         my_content = re.search('<div.*?id="content">(.*?)</div>',unicodePage,re.S)  
  39.         my_content = my_content.group(1)  
  40.         my_content = my_content.replace("<br />","\n")  
  41.         my_content = my_content.replace(" "," ")  
  42.   
  43.         #用字典存储一章的标题和内容  
  44.         onePage = {'title':my_title,'content':my_content}  
  45.   
  46.         #找到页面下方的连接区域  
  47.         foot_link = re.search('<div.*?id="footlink">(.*?)</div>',unicodePage,re.S)  
  48.         foot_link = foot_link.group(1)  
  49.         #在连接的区域找下一页的连接,根据网页特点为第三个  
  50.         nextUrl = re.findall(u'<a.*?href="(.*?)">(.*?)</a>',foot_link,re.S)  
  51.         nextUrl = nextUrl[2][0]  
  52.         # 更新下一次进行抓取的链接  
  53.         self.url = nextUrl  
  54.   
  55.         return onePage  
  56.   
  57.     # 用于加载章节  
  58.     def LoadPage(self):  
  59.         while self.flag:  
  60.             if(len(self.pages) - self.page < 3):  
  61.                 try:  
  62.                     # 获取新的页面  
  63.                     myPage = self.GetPage()  
  64.                     self.pages.append(myPage)  
  65.                 except:  
  66.                     print '无法连接网页!'  
  67.   
  68.     #显示一章  
  69.     def ShowPage(self,curPage):  
  70.             print curPage['title']  
  71.             print curPage['content']  
  72.             print "\n"  
  73.             user_input = raw_input("当前是第 %d 章,回车读取下一章或者输入 quit 退出:" % self.page)  
  74.             if(user_input == 'quit'):  
  75.                 self.flag = False  
  76.             print "\n"  
  77.   
  78.     def Start(self):  
  79.         print u'开始阅读......\n'  
  80.   
  81.         # 新建一个线程  
  82.         thread.start_new_thread(self.LoadPage,())  
  83.   
  84.         # 如果self的page数组中存有元素  
  85.         while self.flag:  
  86.             if self.page <= len(self.pages):  
  87.                 nowPage = self.pages[self.page-1]  
  88.                 self.ShowPage(nowPage)  
  89.                 self.page += 1  
  90.   
  91.         print u"本次阅读结束"  
  92.   
  93.   
  94. #----------- 程序的入口处 -----------  
  95. print u""" 
  96. --------------------------------------- 
  97.    程序:阅读呼叫转移 
  98.    版本:0.2 
  99.    作者:angryrookie 
  100.    日期:2014-07-07 
  101.    语言:Python 2.7 
  102.    功能:按下回车浏览下一章节 
  103. --------------------------------------- 
  104. """  
  105.   
  106. print u'请按下回车:'  
  107. raw_input(' ')  
  108. myBook = Book_Spider()  
  109. myBook.Start()  

1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值