python 小說爬蟲_從零開始寫Python爬蟲 --- 1.7 爬蟲實踐: 排行榜小說批量下載

從零開始寫Python爬蟲 --- 1.7 爬蟲實踐: 排行榜小說批量下載9f1957128c1651917b071e2e73a88f32.jpgEhco

5 個月前

本來只是準備做一個爬起點小說名字的爬蟲,后來想了一下,為啥不順便把小說的內容也爬下來呢?于是我就寫了這個爬蟲,他爬下了各類小說排行榜上的所有章節內容,并保存到本地。仔細想了一下,各種盜版小說閱讀器,是不是就是這樣做的呢?

目標分析:首先來看看我們排行榜的地址:

http://www.qu.la/paihangbang/

我們的目的很明確:

找到各類排行旁的的每一部小說的名字,和在該網站的鏈接:

觀察一下網頁的結構:

a7ad03c4a7ea9bd8f9b838d96af30611.png

我們很容易就能發現,每一個分類都是包裹在:

之中

這種調理清晰的網站,大大方便了我們爬蟲的編寫

小說標題和鏈接:我們在剛才那個div里自己尋找:

玄幻奇幻排行

05-061.擇天記

05-062.大主宰

05-063.太古神王

05-064.雪鷹領主

05-0115.武動乾坤

發現所有的小說都是在一個個列表里,并且里面清晰的定義了:

標題:title = div.a['title']

鏈接:link = 'http://www.qu.la/'

+ div.a['href']

這樣一來,我們只需要在當前頁面找到所有小說的連接,并保存在列表就行了。

列表去重的小技巧:信息的同學會發現,就算是不同類別的小說,也是會重復出現在排行榜的。

這樣無形之間就會浪費我們很多資源,尤其是在面對爬大量網頁的時候。

那么我們如何從抓取的url列表里去重呢?

剛學Python的小伙伴可能會去實現一個循環算法,來去重,

但是Python的強大之處就在于他可以通過及其優美的方式來解決很多問題,這里其實只要一行代碼就能解決:

url_list = list(set(url_list))

這里我們調用了一個list的構造函數set:這樣就能保證列表里沒有重復的元素了。是不是很簡單?

單個小說所有章節鏈接:首先我們從前面獲取到的小說url連接選取一個做實驗:

比如我最愛的擇天記:

http://www.qu.la/book/168/

依然是無比清晰的網頁結構,點個贊:

825faaa1808c065ad80c314977313019.png

《擇天記》正文

序 下山

第一章 我改主意了

第二章 為什么

第九章 我有做錯什么嗎?

我們可以很容易的找到對應章節的連接:

這個代碼是節選,不能直接用!后面會有說明

link='http://www.qu.la/' + url.a['href']

好的,這樣我們就能把一篇小說的所有章節的鏈接爬下來了。

剩下最后一步:爬取文章內容:

文章內容的爬取:首先我們打開一章,并查看他的源代碼:

88b86e5cd37d311e477c54d37515668c.png

我們能發現所有的正文內容,都保存在:

所有的章節名就更簡單了:

第一章 我改主意了

那我們通過bs4庫的各種標簽的查找方法,就能很簡單的找到啦

好了,讓我們看看具體代碼的實現:

代碼的實現:模塊化,函數式編程是一個非常好的習慣,我們堅持把每一個獨立的功能都寫成函數,這樣會使你的代碼簡單又可復用。

網頁抓取頭:def get_html(url):

try:

r = requests.get(url, timeout=30)

r.raise_for_status

# 我手動測試了編碼。并設置好,這樣有助于效率的提升

r.encoding = ('utr-8')

return r.text

except:

return "Someting Wrong!"

獲取排行榜小說及其鏈接:def get_content(url):

'''

爬取每一類型小說排行榜,

按順序寫入文件,

文件內容為 小說名字+小說鏈接

將內容保存到列表

并且返回一個裝滿url鏈接的列表

'''

url_list = []

html = get_html(url)

soup = bs4.BeautifulSoup(html, 'lxml')

# 由于小說排版的原因,歷史類和完本類小說不在一個div里

category_list = soup.find_all('div', class_='index_toplist mright mbottom')

history_finished_list = soup.find_all(

'div', class_='index_toplist mbottom')

for cate in category_list:

name = cate.find('div', class_='toptab').span.string

with open('novel_list.csv', 'a+') as f:

f.write("\n小說種類:{} \n".format(name))

# 我們直接通過style屬性來定位總排行榜

general_list = cate.find(style='display: block;')

# 找到全部的小說名字,發現他們全部都包含在li標簽之中

book_list = general_list.find_all('li')

# 循環遍歷出每一個小說的的名字,以及鏈接

for book in book_list:

link = 'http://www.qu.la/' + book.a['href']

title = book.a['title']

# 我們將所有文章的url地址保存在一個列表變量里

url_list.append(link)

# 這里使用a模式,防止清空文件

with open('novel_list.csv', 'a') as f:

f.write("小說名:{:<} \t 小說地址:{:<} \n".format(title, link))

for cate in history_finished_list:

name = cate.find('div', class_='toptab').span.string

with open('novel_list.csv', 'a') as f:

f.write("\n小說種類:{} \n".format(name))

general_list = cate.find(style='display: block;')

book_list = general_list.find_all('li')

for book in book_list:

link = 'http://www.qu.la/' + book.a['href']

title = book.a['title']

url_list.append(link)

with open('novel_list.csv', 'a') as f:

f.write("小說名:{:<} \t 小說地址:{:<} \n".format(title, link))

return url_list

獲取單本小說的所有章節鏈接:def get_txt_url(url):

'''

獲取該小說每個章節的url地址:

并創建小說文件

'''

url_list = []

html = get_html(url)

soup = bs4.BeautifulSoup(html, 'lxml')

lista = soup.find_all('dd')

txt_name = soup.find('h1').text

with open('/Users/ehco/Documents/codestuff/Python-crawler/小說/{}.txt'.format(txt_name), "a+") as f:

f.write('小說標題:{} \n'.format(txt_name))

for url in lista:

url_list.append('http://www.qu.la/' + url.a['href'])

return url_list, txt_name

獲取單頁文章的內容并保存到本地:這里有個小技巧:

我們從網上趴下來的文件很多時候都是帶著
之類的格式化標簽,

我們可以通過一個簡單的方法把他過濾掉:

html = get_html(url).replace('
', '\n')

我這里單單過濾了一種標簽,并將其替換成‘\n’用于文章的換行,

具體怎么擴展,大家可以開動一下自己的腦袋啦

還有,我這里的代碼是不能直接在你們的機子上用的,

因為在寫入文件的時候,絕對目錄不一樣

def get_one_txt(url, txt_name):

'''

獲取小說每個章節的文本

并寫入到本地

'''

html = get_html(url).replace('
', '\n')

soup = bs4.BeautifulSoup(html, 'lxml')

try:

txt = soup.find('div', id='content').text.replace(

'chaptererror();', '')

title = soup.find('title').text

with open('/Users/ehco/Documents/codestuff/Python-crawler/小說/{}.txt'.format(txt_name), "a") as f:

f.write(title + '\n\n')

f.write(txt)

print('當前小說:{} 當前章節{} 已經下載完畢'.format(txt_name, title))

except:

print('someting wrong')

缺點:本次爬蟲寫的這么順利,更多的是因為爬的網站是沒有反爬蟲技術,以及文章分類清晰,結構優美。

但是,按照我們的這篇文的思路去爬取小說,

我大概計算了一下:

一篇文章需要:0.5s

一本小說(1000張左右):8.5分鐘

全部排行榜(60本):?8.5小時!

是的! 時間太長了!

那么,這種單線程的爬蟲,速度如何能提高呢?

自己洗個多線程模塊?

其實還有更好的方式:下一個大的章節我們將一起學習Scrapy框架

學到那里的時候,我再把這里代碼重構一邊,

你會驚奇的發現,速度幾十倍甚至幾百倍的提高了!

這其實也是多線程的威力!

最后看一下結果吧:排行榜結果:

7ae258b72e1d88fd7539a687df481a90.png

小說結果:

b159d629e9a9a32b2d2c3541ce437621.png

學到這里是不是越來越喜歡爬蟲這個神奇的東西了呢?

加油,更神奇的東西還在后面呢!

每天的學習記錄都會 同步更新到:

微信公眾號: findyourownway

知乎專欄:從零開始寫Python爬蟲 - 知乎專欄

blog :?www.ehcoblog.ml

Github:?Ehco1996/Python-crawler

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/534102.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/534102.shtml
英文地址,請注明出處:http://en.pswp.cn/news/534102.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java 某個字符在字符串中出現的所有位置_Java面試常考核心概念

這篇文章專注于Java基礎知識&#xff0c;不涉及List、Map、多線程、鎖相關的內容&#xff0c;需要的可以查看我的其他博客hofes blog?hhf443.github.ioJDK&JRE&JVMJDK&#xff08;Java Development Kit&#xff09;是針對 Java 開發員的產品&#xff0c;是整個 Java 的…

lan交換和無線教師手冊_簡單幾步,無線路由器變交換機

當原來的路由器lan口不夠用&#xff0c;可以加一個交換機擴展lan口數量&#xff0c;如果需要增加的lan口數量不超過3個可以考慮找臺不用的無線路由器當交換機用。另外&#xff0c;隨著交換機更新家中都有舊無線路由器閑置&#xff0c;完全可以再次利用。下面看一下&#xff0c;…

Linux fast open,Linux內核3.7 TCP Fast Open驗證實例

Linux內核在3.6和3.7合入了TCP Fast Open特性&#xff0c;在3.7.3版本上驗證了一下&#xff0c;I did it!以下是C語言實例()&#xff1a;server端代碼&#xff1a;#include /* See NOTES */#include#include#includeint main(){int portno 5060;socklen_t clilen;char buffer[…

vue 怎么全局到入常量_Vue 中如何定義全局的變量和常量(轉)

17.6k 次閱讀 讀完需要 10 分鐘7Vue 中如何定義全局的變量和常量我想要定義一個變量, 在項目的任何地方都可以訪問到, 不需要每一次使用的時候, 都引入.嘗試1:創建 global.js 并且在其中定義let a 10;在入口文件中引入 global.jsimport ./global.js在項目中使用:a// 報錯發…

revit找不到附加模塊程序集_TensorFlow基礎知識——常用模塊(一)

1本節簡述對于開展深度學習開發的目標而言&#xff0c;我們需要掌握的除了必要的深度學習理論基礎、必要的開發依賴庫基礎知識、基本的開發套路之外&#xff0c;我們還需要掌握它常見的外圍小幫手都有哪些。這些小幫手就是深度學習依賴庫中的其他并不是核心的模塊&#xff0c;但…

android搭建opencv開發環境,Android Studio搭建opencv開發環境

文章不配圖片&#xff0c;閱讀需要有Android開發基礎并熟悉Android Studio。一、搭建基于Java開發環境以下內容介紹如何搭建基于Java jni的opencv開發環境。1、準備工作從opencv官網下載Android平臺開發sdk并解壓&#xff0c;假設解壓后文件夾名為opencv-4.3.0-android-sdk。(此…

99 網絡編程_網絡工程師技能圖譜,看看你會多少技能

技術推動了時代變革&#xff0c;互聯網則加速了這場變革。在蓬勃發展的互聯網浪潮下&#xff0c;網絡作為基礎設施的關鍵紐帶保障著網路流量的順利流通&#xff0c;維持著賽博世界的繁榮。而在這繁榮之下&#xff0c;生存著這樣一個群體——網絡工程獅&#xff0c;為網絡紐帶保…

python 3.8.0安卓_Python for Mac v3.8.0 官方最新版

Python for Mac是一款全新推出的編程工具&#xff0c;所有 python.org macOS 安裝程序都附帶了 OpenSSL 的內置副本。此外&#xff0c;還有一個針對 macOS 10.9 的新增安裝程序變體&#xff0c;其中包含 Tcl / Tk 8.6的內置版本&#xff0c;有需要的朋友快來下載試試吧!Python …

線程join_Java 并發編程:線程間的協作(wait/notify/sleep/yield/join)

點擊上方“Coder編程”&#xff0c;選擇“置頂公眾號”技術文章第一時間送達&#xff01;并發編程.png每天進步一點&#xff0c;不做curd工程師與Api調用工程師 歡迎訪問個人博客網站&#xff1a;https://www.coder-programming.cn/ 作者&#xff1a;liuxiaopeng | http://www…

4位先行進位電路 logisim_你真的了解74系列集成電路嗎?讓我幫你總結一下

74系列集成電路大致可分為6大類&#xff1a;74(標準型)74LS(低功耗肖特基)74S(肖特基)74ALS(先進低功耗肖特基)74AS(先進肖特基)74F(高速)HC為COMS工作電平&#xff1b;HCT為TTL工作電平&#xff0c;可與74LS系列互換使用HCU適用于無緩沖級的CMOS電路。這9種74系列產品&#xf…

android ios av tv,iOS使用AVPlayer制作戰旗TvDEMO OC版

在視頻教學中看到一個別人寫的戰旗TvDEMO寫得很好&#xff0c;于是自己動手試著制作一個。效果如下圖所示主界面豎屏播放橫屏播放點擊出現工具欄視頻播放使用的是AVPlayer,具體的使用方式如下//---PlayView---_playView [[UIView alloc]init];_playView.frame CGRectMake(0, …

matlab 子圖title的位置_matlab 畫圖基本介紹

1.在命令窗口輸入命令時&#xff0c;可以不必每輸入一條命令就按enter鍵執行&#xff0c;可以在輸入幾行后一同運行。方法是&#xff1a;換行時&#xff0c;只要在按住<shift>鍵的同時按<enter>鍵即可&#xff0c;否則matlab就會執行上面輸入的所有語句。2.如何將數…

python程序打包成安卓app教程_Python打包方法基本應用方式介紹

Python編程語言是一款功能強大的免費開源的通用型計算機程序應用語言&#xff0c;對于經驗豐富的開發人員來說&#xff0c;掌握這樣一款語言在其程序開發中是一個比較重要的選擇。我們今天就先來了解一下python打包方法的相關應用。 一、簡介 py2exe是一個將Python腳本轉換成wi…

android添加刪除項目,編寫android計算器添加刪除按鈕,出現很抱歉,XX項目已停止運行。...

這是刪除按鈕監聽代碼&#xff1a;//del 按鈕的監聽btnDel (Button) findViewById(R.id.delete);btnDel.setOnClickListener(new OnClickListener() {Overridepublic void onClick(View view) {btnDel.setOnClickListener(this);//短按//btnDel.setOnLongClickListener(this);…

二元一次方程有唯一解的條件_人教版初中數學七年級下冊用適當方法解二元一次方程組公開課優質課課件教案視頻...

解二元一次方程組---加減法一、教學目的&#xff1a;1&#xff0e;使學生掌握用加減法解二元一次方程組的步驟。2&#xff0e;熟練運用加減法解二元一次方程組。3&#xff0e;培養學生分析問題、解決問題的能力。二、教學重點、難點和關鍵&#xff08;一&#xff09;重點&#…

為什么從網頁上打印怎們好像被縮放_全網最詳細關于3D打印的zbrush技術

這個小教程旨在為剛開始對3D打印感興趣的新人朋友提供一些快速上手小技巧&#xff0c;以便在zbrush中制作適合桌面FDM 3D打印的創作&#xff0c;本次小教程需要讀者已經有一些zbrush基礎知識。1設置系統單位導入1英尺的box&#xff0c;1英尺X1英尺X1英尺。一旦導入到場景中&…

android圖片瀏覽遠近,快圖瀏覽編輯圖片方法介紹_怎么編輯圖片_3DM手游

既然是圖片管理工具&#xff0c;那么快圖瀏覽肯定也是少不了圖片編輯功能的。如何使用快圖瀏覽編輯圖片呢&#xff1f;下面小編帶來的詳細的使用方法&#xff0c;有需要的小伙伴一起來看看吧&#xff01;編輯照片方法介紹&#xff1a;1.第一步&#xff0c;下載安裝快圖瀏覽&…

h5微信本地調試 vue_vueh5中使用微信sdk

微信官方sdk教程安裝vue 微信sdk 使用NPM安裝&#xff0c;不會的百度學npm install jweixin-module --save創建一個wxsdk.js 文件// 引入微信sdkvar jweixin require(jweixin-module);export default {//判斷是否在微信中isWechat: function() {var ua window.navigator.user…

matlab 三維 作圖 坐標軸_MATLAB學習——MATLAB中的三維繪圖指令

2 基本XYZ立體繪圖命令mesh和plot是三度空間立體繪圖的基本命令&#xff0c;mesh可畫出立體網狀圖&#xff0c;plot則可畫出立體曲面圖&#xff0c;兩者產生的圖形都會依高度而有不同顏色。下列命令可畫出由函數形成的立體網狀圖: xlinspace(-2, 2, 25); % 在x軸上取25點 ylins…

說說python程序的執行過程_表示說的詞語

展開全部1、奉勸 [ fng qun ] 釋義&#xff1a;敬辭。鄭重勸說62616964757a686964616fe58685e5aeb931333365653331。 造句&#xff1a;我們厭惡那些陰險的惡人&#xff0c;奉勸他們改惡為善&#xff0c;才能得到社會的原諒&#xff01; 2、勸告 [ qun go ] 釋義&#xff1a;拿道…