欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

編寫Python腳本抓取網(wǎng)絡(luò)小說來制作自己的閱讀器

 更新時(shí)間:2015年08月20日 12:09:51   作者:一線涯  
這篇文章主要介紹了編寫Python腳本抓取網(wǎng)絡(luò)小說來制作自己的閱讀器的方法,包括對(duì)小說的章節(jié)排列等方面的優(yōu)化,對(duì)于Python學(xué)習(xí)者來說非常具有實(shí)踐意義!需要的朋友可以參考下

你是否苦惱于網(wǎng)上無法下載的“小說在線閱讀”內(nèi)容?或是某些文章的內(nèi)容讓你很有收藏的沖動(dòng),卻找不到一個(gè)下載的鏈接?是不是有種自己寫個(gè)程序把全部搞定的沖動(dòng)?是不是學(xué)了 python,想要找點(diǎn)東西大展拳腳,告訴別人“哥可是很牛逼的!”?那就讓我們開始吧! 哈哈~
    好吧,我就是最近寫 Yii 寫多了,想找點(diǎn)東西調(diào)劑一下.... = =

    本項(xiàng)目以研究為目的,所有版權(quán)問題我們都是站在作者的一邊,以看盜版小說為目的的讀者們請(qǐng)自行面壁!
    說了這么多,我們要做的就是把小說正文的內(nèi)容從網(wǎng)頁上爬下來,我們的研究對(duì)象是全本小說網(wǎng)....再次聲明,不對(duì)任何版權(quán)負(fù)責(zé)....
    一開始先做最基礎(chǔ)的內(nèi)容,就是把某一章的內(nèi)容抓取下來。

    環(huán)境:Ubuntu, Python 2.7

    基礎(chǔ)知識(shí)
    這個(gè)程序涉及到的知識(shí)點(diǎn)有幾個(gè),在這里列出來,不詳細(xì)講,有疑問的直接百度會(huì)有一堆的。
    1.urllib2 模塊的 request 對(duì)像來設(shè)置 HTTP 請(qǐng)求,包括抓取的 url,和偽裝瀏覽器的代理。然后就是 urlopen 和 read 方法,都很好理解。
    2.chardet 模塊,用于檢測(cè)網(wǎng)頁的編碼。在網(wǎng)頁上抓取數(shù)據(jù)很容易遇到亂碼的問題,為了判斷網(wǎng)頁是 gtk 編碼還是 utf-8 ,所以用 chardet 的 detect 函數(shù)進(jìn)行檢測(cè)。在用 Windows 的同學(xué)可以在這里 http://download.csdn.net/detail/jcjc918/8231371 下載,解壓到 python 的 lib 目錄下就好。
    3. decode 函數(shù)將字符串從某種編碼轉(zhuǎn)為 unicode 字符,而 encode 把 unicode 字符轉(zhuǎn)為指定編碼格式的字符串。
     4. re 模塊正則表達(dá)式的應(yīng)用。search 函數(shù)可以找到和正則表達(dá)式對(duì)應(yīng)匹配的一項(xiàng),而 replace 則是把匹配到的字符串替換。

    思路分析:
    我們選取的 url 是 http://www.quanben.com/xiaoshuo/0/910/59302.html,斗羅大陸的第一章。你可以查看網(wǎng)頁的源代碼,會(huì)發(fā)現(xiàn)只有一個(gè) content 標(biāo)簽包含了所有章節(jié)的內(nèi)容,所以可以用正則把 content 的標(biāo)簽匹配到,抓取下來。試著把這一部分內(nèi)容打印出來,會(huì)發(fā)現(xiàn)很多 <br /> 和 &nbsp,<br /> 要替換成換行符, &nbsp 是網(wǎng)頁中的占位符,即空格,替換成空格就好。這樣一章的內(nèi)容就很美觀的出來了。完整起見,同樣用正則把標(biāo)題爬下來。

    程序

# -*- coding: utf-8 -*- 
 
import urllib2 
import re 
import chardet 
 
 
class Book_Spider: 
 
  def __init__(self): 
    self.pages = [] 
 
  # 抓取一個(gè)章節(jié) 
  def GetPage(self): 
    myUrl = "http://www.quanben.com/xiaoshuo/0/910/59302.html"; 
    user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' 
    headers = { 'User-Agent' : user_agent } 
    request = urllib2.Request(myUrl, headers = headers) 
    myResponse = urllib2.urlopen(request) 
    myPage = myResponse.read() 
 
    #先檢測(cè)網(wǎng)頁的字符編碼,最后統(tǒng)一轉(zhuǎn)為 utf-8 
    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") 
 
    try: 
      #抓取標(biāo)題 
      my_title = re.search('<h1>(.*?)</h1>',unicodePage,re.S) 
      my_title = my_title.group(1) 
    except: 
      print '標(biāo)題 HTML 變化,請(qǐng)重新分析!' 
      return False 
     
    try: 
      #抓取章節(jié)內(nèi)容 
      my_content = re.search('<div.*?id="htmlContent" class="contentbox">(.*?)<div',unicodePage,re.S) 
      my_content = my_content.group(1) 
    except: 
      print "內(nèi)容 HTML 變化,請(qǐng)重新分析!" 
      return False 
     
    #替換正文中的網(wǎng)頁代碼 
    my_content = my_content.replace("<br />","\n") 
    my_content = my_content.replace(" "," ") 
 
    #用字典存儲(chǔ)一章的標(biāo)題和內(nèi)容 
    onePage = {'title':my_title,'content':my_content} 
    return onePage 
 
 
  # 用于加載章節(jié) 
  def LoadPage(self): 
    try: 
      # 獲取新的章節(jié) 
      myPage = self.GetPage() 
       
      if myPage == False: 
        print '抓取失??!' 
        return False 
       
      self.pages.append(myPage) 
    except: 
      print '無法連接服務(wù)器!' 
 
  #顯示一章 
  def ShowPage(self,curPage): 
      print curPage['title'] 
      print curPage['content'] 
 
  def Start(self): 
    print u'開始閱讀......\n' 
    #把這一頁加載進(jìn)來 
    self.LoadPage() 
    # 如果self的pages數(shù)組中存有元素 
    if self.pages: 
      nowPage = self.pages[0] 
      self.ShowPage(nowPage) 
 
 
#----------- 程序的入口處 ----------- 
print u""" 
--------------------------------------- 
  程序:閱讀呼叫轉(zhuǎn)移 
  版本:0.1 
  作者:angryrookie 
  日期:2014-07-05 
  語言:Python 2.7 
  功能:按下回車瀏覽章節(jié) 
--------------------------------------- 
""" 
 
print u'請(qǐng)按下回車:' 
raw_input() 
myBook = Book_Spider() 
myBook.Start() 

程序運(yùn)行完在我這里可是很好看的,不信請(qǐng)看:^_^

理所當(dāng)然地,接下來我們要把整本小說都爬下來。首先,我們要把程序從原來的讀完一章就結(jié)束,改成讀完一章之后可以繼續(xù)進(jìn)行下一章的閱讀。
    注意到每個(gè)小說章節(jié)的網(wǎng)頁下面都有下一頁的鏈接。通過查看網(wǎng)頁源代碼,稍微整理一下(&nbsp; 不顯示了),我們可以看到這一部分的 HTML 是下面這種格式的:

<div id="footlink"> 
 <script type="text/javascript" charset="utf-8" src="/scripts/style5.js"></script> 
 <a >上一頁</a>   
 <a >返回目錄</a>   
 <a >下一頁</a> 
</div> 

     上一頁 、返回目錄、下一頁都在一個(gè) id 為 footlink  的 div 中,如果想要對(duì)每個(gè)鏈接進(jìn)行匹配的話,會(huì)抓取到網(wǎng)頁上大量的其他鏈接,但是 footlink 的 div 只有一個(gè)??!我們可以把這個(gè) div 匹配到,抓下來,然后在這個(gè)抓下來的 div  里面再匹配 <a> 的鏈接,這時(shí)就只有三個(gè)了。只要取最后一個(gè)鏈接就是下一頁的 url 的,用這個(gè) url 更新我們抓取的目標(biāo) url ,這樣就能一直抓到下一頁。用戶閱讀邏輯為每讀一個(gè)章節(jié)后,等待用戶輸入,如果是 quit 則退出程序,否則顯示下一章。

     基礎(chǔ)知識(shí):
     上一篇的基礎(chǔ)知識(shí)加上 Python 的 thread 模塊.

     源代碼:

# -*- coding: utf-8 -*- 
 
import urllib2 
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/10/10412/2095096.html" 
 
  # 將抓取一個(gè)章節(jié) 
  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標(biāo)記 
    try: 
      #抓取標(biāo)題 
      my_title = re.search('<h1>(.*?)</h1>',unicodePage,re.S) 
      my_title = my_title.group(1) 
    except: 
      print '標(biāo)題 HTML 變化,請(qǐng)重新分析!' 
      return False 
     
    try: 
      #抓取章節(jié)內(nèi)容 
      my_content = re.search('<div.*?id="htmlContent" class="contentbox">(.*?)<div',unicodePage,re.S) 
      my_content = my_content.group(1) 
    except: 
      print "內(nèi)容 HTML 變化,請(qǐng)重新分析!" 
      return False 
     
    my_content = my_content.replace("<br />","\n") 
    my_content = my_content.replace(" "," ") 
 
    #用字典存儲(chǔ)一章的標(biāo)題和內(nèi)容 
    onePage = {'title':my_title,'content':my_content} 
 
    try: 
      #找到頁面下方的連接區(qū)域 
      foot_link = re.search('<div.*?class="chapter_Turnpage">(.*?)</div>',unicodePage,re.S) 
      foot_link = foot_link.group(1) 
      #在連接的區(qū)域找下一頁的連接,根據(jù)網(wǎng)頁特點(diǎn)為第三個(gè) 
      nextUrl = re.findall(u'<a.*?href="(.*?)".*?>(.*?)</a>',foot_link,re.S) 
      nextUrl = nextUrl[2][0] 
      # 更新下一次進(jìn)行抓取的鏈接 
      self.url = nextUrl 
    except: 
      print "底部鏈接變化,請(qǐng)重新分析!" 
      return False 
 
    return onePage 
 
  # 用于加載章節(jié) 
  def LoadPage(self): 
    while self.flag: 
      if(len(self.pages) - self.page < 3): 
        try: 
          # 獲取新的頁面 
          myPage = self.GetPage() 
 
          if myPage == False: 
            print '抓取失?。? 
            self.flag = False 
       
          self.pages.append(myPage) 
        except: 
          print '無法連接網(wǎng)頁!' 
          self.flag = False 
 
  #顯示一章 
  def ShowPage(self,curPage): 
      print curPage['title'] 
      print curPage['content'] 
      print "\n" 
      user_input = raw_input("當(dāng)前是第 %d 章,回車讀取下一章或者輸入 quit 退出:" % self.page) 
      if(user_input == 'quit'): 
        self.flag = False 
      print "\n" 
 
  def Start(self): 
    print u'開始閱讀......\n' 
 
    # 新建一個(gè)線程 
    thread.start_new_thread(self.LoadPage,()) 
 
    # 如果self的page數(shù)組中存有元素 
    while self.flag: 
      if self.page <= len(self.pages): 
        nowPage = self.pages[self.page-1] 
        self.ShowPage(nowPage) 
        self.page += 1 
 
    print u"本次閱讀結(jié)束" 
 
 
#----------- 程序的入口處 ----------- 
print u""" 
--------------------------------------- 
  程序:閱讀呼叫轉(zhuǎn)移 
  版本:0.2 
  作者:angryrookie 
  日期:2014-07-07 
  語言:Python 2.7 
  功能:按下回車瀏覽下一章節(jié) 
--------------------------------------- 
""" 
 
print u'請(qǐng)按下回車:' 
raw_input(' ') 
myBook = Book_Spider() 
myBook.Start() 

現(xiàn)在這么多小說閱讀器,我們只需要把我們要的小說抓取到本地的 txt 文件里就好了,然后自己選個(gè)閱讀器看,怎么整都看你了。

    其實(shí)上個(gè)程序我們已經(jīng)完成了大部分邏輯,我們接下來的改動(dòng)只需要把抓取到每一章的時(shí)候不用顯示出來,而是存入 txt 文件之中。另外一個(gè)是程序是不斷地根據(jù)下一頁的 Url 進(jìn)行抓取的,那么什么時(shí)候結(jié)束呢?注意當(dāng)?shù)竭_(dá)小說的最后一章時(shí)下一頁的鏈接是和返回目錄的鏈接是一樣的。所以我們抓取一個(gè)網(wǎng)頁的時(shí)候就把這兩個(gè)鏈接拿出來,只要出現(xiàn)兩個(gè)鏈接一樣的時(shí)候,就停止抓取。最后就是我們這個(gè)程序不需要多線程了,我們只要一個(gè)不斷在抓取小說頁面的線程就行了。
    不過,小說章節(jié)多一點(diǎn)時(shí)候,等待完成的時(shí)間會(huì)有點(diǎn)久。目前就不考慮這么多了,基本功能完成就 OK....

    基礎(chǔ)知識(shí):前面的基礎(chǔ)知識(shí) - 多線程知識(shí) + 文件操作知識(shí)。

     源代碼:

# -*- 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" 
 
  # 將抓取一個(gè)章節(jié) 
  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標(biāo)記 
    try: 
      #抓取標(biāo)題 
      my_title = re.search('<h1>(.*?)</h1>',unicodePage,re.S) 
      my_title = my_title.group(1) 
    except: 
      print '標(biāo)題 HTML 變化,請(qǐng)重新分析!' 
      return False 
     
    try: 
      #抓取章節(jié)內(nèi)容 
      my_content = re.search('<div.*?id="htmlContent" class="contentbox">(.*?)<div',unicodePage,re.S) 
      my_content = my_content.group(1) 
    except: 
      print "內(nèi)容 HTML 變化,請(qǐng)重新分析!" 
      return False 
     
    my_content = my_content.replace("<br />","\n") 
    my_content = my_content.replace(" "," ") 
 
    #用字典存儲(chǔ)一章的標(biāo)題和內(nèi)容 
    onePage = {'title':my_title,'content':my_content} 
 
    try: 
      #找到頁面下方的連接區(qū)域 
      foot_link = re.search('<div.*?class="chapter_Turnpage">(.*?)</div>',unicodePage,re.S) 
      foot_link = foot_link.group(1) 
      #在連接的區(qū)域找下一頁的連接,根據(jù)網(wǎng)頁特點(diǎn)為第三個(gè) 
      nextUrl = re.findall(u'<a.*?href="(.*?)".*?>(.*?)</a>',foot_link,re.S) 
      #目錄鏈接 
      dir_url = nextUrl[1][0] 
      nextUrl = nextUrl[2][0] 
      # 更新下一次進(jìn)行抓取的鏈接 
      self.url = nextUrl 
 
      if(dir_url == nextUrl): 
        self.flag = False 
         
      return onePage 
    except: 
      print "底部鏈接變化,請(qǐng)重新分析!" 
      return False 
 
  # 用于加載章節(jié) 
  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 '無法連接服務(wù)器!' 
        self.flag = False 
         
    f_txt.close() 
 
  def Start(self): 
    print u'開始下載......\n' 
 
    self.downloadPage() 
 
 
    print u"下載完成" 
 
 
#----------- 程序的入口處 ----------- 
print u""" 
--------------------------------------- 
  程序:閱讀呼叫轉(zhuǎn)移 
  版本:0.3 
  作者:angryrookie 
  日期:2014-07-08 
  語言:Python 2.7 
  功能:按下回車開始下載 
--------------------------------------- 
""" 
 
print u'請(qǐng)按下回車:' 
raw_input(' ') 
myBook = Book_Spider() 
myBook.Start() 

相關(guān)文章

  • Django 實(shí)現(xiàn)將圖片轉(zhuǎn)為Base64,然后使用json傳輸

    Django 實(shí)現(xiàn)將圖片轉(zhuǎn)為Base64,然后使用json傳輸

    這篇文章主要介紹了Django 實(shí)現(xiàn)將圖片轉(zhuǎn)為Base64,然后使用json傳輸,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • pytest生成Allure報(bào)告以及查看報(bào)告的實(shí)現(xiàn)

    pytest生成Allure報(bào)告以及查看報(bào)告的實(shí)現(xiàn)

    本文主要介紹了pytest生成Allure報(bào)告以及查看報(bào)告的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Python 異步之如何保護(hù)任務(wù)免于取消詳解

    Python 異步之如何保護(hù)任務(wù)免于取消詳解

    這篇文章主要為大家介紹了Python 異步之如何保護(hù)任務(wù)免于取消示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • python之tensorflow手把手實(shí)例講解斑馬線識(shí)別實(shí)現(xiàn)

    python之tensorflow手把手實(shí)例講解斑馬線識(shí)別實(shí)現(xiàn)

    目前智慧城市的發(fā)展,人們生活處處有科技,比如人臉識(shí)別,智慧交通,無人駕駛等前沿的科技產(chǎn)品也都融入了人們生活中;本篇文章帶你從頭開始實(shí)現(xiàn)斑馬線識(shí)別
    2021-09-09
  • Python解析pcap文件示例

    Python解析pcap文件示例

    這篇文章主要為大家介紹了Python解析pcap文件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • python利用urllib實(shí)現(xiàn)爬取京東網(wǎng)站商品圖片的爬蟲實(shí)例

    python利用urllib實(shí)現(xiàn)爬取京東網(wǎng)站商品圖片的爬蟲實(shí)例

    下面小編就為大家?guī)硪黄猵ython利用urllib實(shí)現(xiàn)爬取京東網(wǎng)站商品圖片的爬蟲實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • python怎么創(chuàng)建新文件代碼舉例

    python怎么創(chuàng)建新文件代碼舉例

    Python創(chuàng)建新文件有多種方法,包括使用open函數(shù)、with語句和Pathlib模塊,這篇文章主要給大家介紹了關(guān)于python怎么創(chuàng)建新文件的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • python中時(shí)間模塊的基本使用教程

    python中時(shí)間模塊的基本使用教程

    這篇文章主要給大家介紹了關(guān)于python中時(shí)間模塊的基本使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 簡(jiǎn)單介紹Python中的RSS處理

    簡(jiǎn)單介紹Python中的RSS處理

    這篇文章主要介紹了簡(jiǎn)單介紹Python中的RSS處理,本文來自于IBM官方開發(fā)者技術(shù)文檔,需要的朋友可以參考下
    2015-04-04
  • python中的列表推導(dǎo)淺析

    python中的列表推導(dǎo)淺析

    這篇文章主要介紹了python中的列表推導(dǎo),需要的朋友可以參考下
    2014-04-04

最新評(píng)論