知識就像碎布,記得「縫一縫」,你才能華麗麗地亮相。html
這次實戰從網上爬取小說,須要使用到Beautiful Soup。
Beautiful Soup爲python的第三方庫,能夠幫助咱們從網頁抓取數據。
它主要有以下特色:前端
win命令行下:python
pip install beautifusoup4
你們能夠參考文檔來學習(中文版的哦):正則表達式
[http://beautifulsoup.readthedocs.io/zh_CN/latest/#id8]
對於本次爬蟲任務,只要瞭解如下幾點基礎內容就能夠完成:
1.Beautiful Soup的對象種類:瀏覽器
2.遍歷文檔樹:find、find_all、find_next和children
3.一點點HTML和CSS知識(沒有也將就,現學就能夠)學習
本次爬取小說的網站爲136書屋。
先打開花千骨小說的目錄頁,是這樣的。網站
咱們的目的是找到每一個目錄對應的url,而且爬取其中地正文內容,而後放在本地文件中。ui
首先,目錄頁左上角有幾個能夠提升你這次爬蟲成功後成就感的字眼:暫不提供花千骨txt全集下載。
繼續往下看,發現是最新章節板塊,而後即是全書的全部目錄。咱們分析的對象即是全書全部目錄。點開其中一個目錄,咱們即可以都看到正文內容。編碼
按F12打開審查元素菜單。能夠看到網頁前端的內容都包含在這裏。url
咱們的目的是要找到全部目錄的對應連接地址,爬取每一個地址中的文本內容。
有耐心的朋友能夠在裏面找到對應的章節目錄內容。有一個簡便方法是點擊審查元素中左上角箭頭標誌的按鈕,而後選中相應元素,對應的位置就會加深顯示。
這樣咱們能夠看到,每一章的連接地址都是有規則地存放在<li>中。而這些<li>又放在<div id="book_detail" class="box1">中。
我不停地強調「咱們的目的」是要告訴你們,思路很重要。爬蟲不是約pao,矇頭就上不可取。
剛纔已經分析過網頁結構。咱們能夠直接在瀏覽器中打開對應章節的連接地址,而後將文本內容提取出來。
咱們要爬取的內容全都包含在這個<div>裏面。
代碼整理以下:
from urllib import request from bs4 import BeautifulSoup if __name__ == '__main__': # 第8章的網址 url = 'http://www.136book.com/huaqiangu/ebxeew/' head = {} # 使用代理 head['User-Agent'] = 'Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19' req = request.Request(url, headers = head) response = request.urlopen(req) html = response.read() # 建立request對象 soup = BeautifulSoup(html, 'lxml') # 找出div中的內容 soup_text = soup.find('div', id = 'content') # 輸出其中的文本 print(soup_text.text)
運行結果以下:
這樣,單章節內容爬取就大功告成了。
單章節爬蟲咱們能夠直接打開對應的章節地址解析其中的文本,全集爬蟲咱們不可能讓爬蟲程序在每章節網頁內中跑一遍,如此還不如複製、粘貼來的快。
咱們的思路是先在目錄頁中爬取全部章節的連接地址,而後再爬取每一個連接對應的網頁中的文本內容。說來,就是比單章節爬蟲多一次解析過程,須要用到Beautiful Soup遍歷文檔樹的內容。
在思路分析中,咱們已經瞭解了目錄頁的結構。全部的內容都放在一個<div id="book_detail" class="box1">中。
這兒有兩個如出一轍的<div id="book_detail" class="box1">。
第一個<div>包含着最近更新的章節,第二個<div>包含着全集內容。
請注意,咱們要爬取的是第二個<div>中的內容。
代碼整理以下:
from urllib import request from bs4 import BeautifulSoup if __name__ == '__main__': # 目錄頁 url = 'http://www.136book.com/huaqiangu/' head = {} head['User-Agent'] = 'Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19' req = request.Request(url, headers = head) response = request.urlopen(req) html = response.read() # 解析目錄頁 soup = BeautifulSoup(html, 'lxml') # find_next找到第二個<div> soup_texts = soup.find('div', id = 'book_detail', class_= 'box1').find_next('div') # 遍歷ol的子節點,打印出章節標題和對應的連接地址 for link in soup_texts.ol.children: if link != '\n': print(link.text + ': ', link.a.get('href'))
執行結果如圖:
將每一個解析出來的連接循環代入到url中解析出來,並將其中的文本爬取出來,而且寫到本地F:/huaqiangu.txt中。
代碼整理以下:
from urllib import request from bs4 import BeautifulSoup if __name__ == '__main__': url = 'http://www.136book.com/huaqiangu/' head = {} head['User-Agent'] = 'Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19' req = request.Request(url, headers = head) response = request.urlopen(req) html = response.read() soup = BeautifulSoup(html, 'lxml') soup_texts = soup.find('div', id = 'book_detail', class_= 'box1').find_next('div') # 打開文件 f = open('F:/huaqiangu.txt','w') # 循環解析連接地址 for link in soup_texts.ol.children: if link != '\n': download_url = link.a.get('href') download_req = request.Request(download_url, headers = head) download_response = request.urlopen(download_req) download_html = download_response.read() download_soup = BeautifulSoup(download_html, 'lxml') download_soup_texts = download_soup.find('div', id = 'content') # 抓取其中文本 download_soup_texts = download_soup_texts.text # 寫入章節標題 f.write(link.text + '\n\n') # 寫入章節內容 f.write(download_soup_texts) f.write('\n\n') f.close()
執行結果顯示 [Finished in 32.3s] 。
打開F盤查看花千骨文件。
爬蟲成功。備好紙巾,快快去感覺尊上和小骨的虐戀吧。
代碼還有不少改進的地方。例如文本中包含廣告的js代碼能夠去除,還能夠加上爬蟲進度顯示等等。實現這些功能須要包含正則表達式和os模塊知識,就很少說了,你們能夠繼續完善。
碼字辛苦,碼代碼費神,文字和代碼同碼更是艱辛無比。若是您以爲文章有那麼一丟丟價值,請不要吝嗇您的讚揚。