用Python從網頁爬取數據,網上相關文章很多,但能讓零基礎初學者輕松上手的卻很少。可能是有的作者覺得有些知識點太簡單不值得花費精力講,結果是難者不會會者不難,初學者常常因此而蒙圈。本人也是小白,剛摸索著爬了兩個簡單的網頁數據,經歷了初學者易犯的各種糊涂,特總結分享一下,希望能對小白們有用。
1、本文代碼環境:python3.7,requests模塊、BeautifulSoup解析庫
python爬網絡數據,方法很多。不同的python版本、不同的模塊、庫,對應代碼都不同。所以,在看他人代碼時,需要搞清代碼環境所用的版本和使用的模塊庫等信息。因為如果環境不同,相同的代碼也可能沒用。初學者往往看到一篇文章講的代碼,復制過來就用,結果就是各種錯誤,這就是因為環境不同造成的。
沒有模塊的,pip安裝一下就好。安裝方法:點擊電腦左下角開始——輸入cmd回車,彈出cmd.exe界面——在界面上輸入pip install requests回車,稍后,提示安裝成功即完成了requests模塊的安裝。BeautifulSoup解析庫是屬于bs4模塊的一個功能塊,所以,用pip安裝時,要安裝pip install bs4。
2、爬蟲4部曲:發出請求——獲得網頁——解析內容——保存內容
建好了代碼環境,就可以開始爬數據了,無論什么代碼環境,爬蟲核心都是這4步。對新手來說,每一步都不簡單,我們通過一個簡單的爬取一篇小說代碼,來看看到底是怎么爬數據的。
3、爬取網絡小說
3-1 擬爬取的網絡小說截圖
如圖3-1,我們試著把這篇小說爬下來保存為txt文件,按照爬蟲4部曲,我們逐步來看:
1)、發出請求
用代碼向網絡發出請求,請求訪問某個網址,首先我們得在代碼中給出具體的網址信息,比如上面截圖的網址是:https://www.biqiuge.com/book/4772/2940354.html
那這個網址是怎么得到的呢,常規方法是通過瀏覽器的開發者工具,我是用的360瀏覽器,點擊右上角的工具菜單,點擊開發者工具即可,打開后的界面如下圖3-2:
圖3-2 開發者工具窗口
頂部菜單選擇Network,中間圓圈選擇Preview,通過選擇左側紅色方框內的不同選項,觀察Preview下部的內容,當能看到我們想要的文字時人(如圖3-3),就說明找到了。
圖3-3 箭頭指示的就是準備爬取的數據
這時點擊Preview左側的Header面板,得到下圖3-4中的url就是我們要找的網址。復制后,粘貼到代碼里就能發出請求了。
圖3-4 找到請求的網址
有細心的會看到,這個網址和我們平常瀏覽網頁時地址欄里的網址一樣啊,還用這么麻煩?
3-5 瀏覽器地址欄網址
這兩個網址確實是一樣的,是不用這么麻煩,直接從地址欄復制就可以。但很多時候,我們要爬取的網頁數據并不在瀏覽器地址欄的那個網址里,這個時候就需要通過上面的那個開發者工具方法去找。
有了網址,發出請求的代碼為:
url = "https://www.biqiuge.com/book/4772/2940354.html" # 要爬取數據的網址
response = requests.get(url) #發出訪問請求,獲得對應網頁
訪問請求的反饋結果放在response里了,這時我們用print(response)看看這個結果到底是什么?運行結果為:<Response [200]>
這是個什么鬼?怎么不是我們想要的網頁內容呢?解釋一下:
運行結果的意思是:響應狀態為成功。可以放心寫后面的代碼了。如果出現數字404,就是沒找到頁面的意思,響應不成功。響應結果還需要解析才能得到網頁內容。
2)、獲得網頁
上面說了,已經請求訪問并響應成功了,接下來就是如何獲得具體網頁內容了。
soup = BeautifulSoup(response.content, 'lxml') # 將獲得的網頁內容解析寫入soup備用
我們用print(soup)看一下結果,就會得到下圖3-6的結果:
3-6 代碼得到的網頁內容
內容與前面在Preview里看到的一樣,說明已經成功獲得了網頁內容。
3)、解析網頁內容,獲得數據
所有要爬取的數據,都在上面的soup結果里,但還有更多是我們不需要的數據。所以接下來第3步就是對上面的結果內容進行操作,以獲得我們想要的內容。
1)根據目標,我們首先要獲得小說的標題和章節標題
在開發者工具里,分析網頁內容,發現我們的目標之一小說和章節的標題分別位于下圖所示位置:
圖3-7 找到標題所處位置
A、小說標題“圣墟”在下面兩個位置都出現過,寫解析代碼就可以了:
<a href="/book/4772/">圣墟</a>
<a href='https://www.biqiuge.com/book/4772/' target='_blank' title="圣墟">圣墟</a>
很明顯第一個相對比簡單點,所以,我們通過解析第一個位置內容來提取出標題“圣墟”
t1 = soup.find('a', href="/book/4772/"').get_text()
代碼解析: 上面兩處標題都位于<a,....../a>之間,所以“a”就是我們要用的第一個參數,由于有a參數的代碼還有很多,為了精準定位就是這個位置的a,我們發現屬性href的值不同而且貌似是獨一無二的,所以將其作為關鍵字放進代碼里,就得到了此處的這段代碼。然后用.get_text()將這段代碼里的文字給爬取出來,就得到了我們最終想要的小說標題——“圣墟”。上面的代碼如果將href的參數值改為:'https://www.biqiuge.com/book/4772/',也能得到相同的結果
B、章節標題在網頁代碼中也出現過多次,但是我們只需找到一處解析得到即可,根據上面的經驗,我們選最簡單的一處為:
<h1>第一章 沙漠中的彼岸花</h1>
編寫代碼:
t2 = soup.find('h1').get_text()
2)獲得小說內容
繼續分析網頁代碼,發現小說內容的位置為:
<div id="content" class="showtxt"><script>App2();</script><br /> 大漠孤煙直......
說明小說內容位于<div ....../div >之間,所以將div作為第一個參數,由于div出現了很多次,所以我們需要繼續用此處獨有的參數作為關鍵字,我們將id="content" class="showtxt"同時作為參數放到代碼里,這樣代碼就為:
tt = soup.find('div', id="content", class="showtxt").get_text()
此時,由于class在python里代表“類”,為敏感詞,作為關鍵字放在代碼里容易混淆,所以我們將敏感詞作為關鍵字時,需要在其后面加一個下劃線,將代碼class="showtxt"改為:class_="showtxt"。運行后,小說內容就已經在tt里了。我們可以通過print(tt)看到效果。
4)、保存內容
雖然小說標題、內容都已經爬取到了,但到哪里看呢,我們不可能每次都用python用print()運行后看。我們可以將剛才爬取到的標題、內容,寫入到一個txt文件里。這就用到os模塊了。
此時運行程序,就能在e盤發現已新生成了文件“小說.txt文件",打開,發現,所有想要的內容已經寫入到文件里了如圖3-8。但是小說內容沒有換行,閱讀起來不方便,且前面有個多余的app2()。
圖3-8 爬取的效果
為了達到更好的效果,我們將代碼:
tt = soup.find('div', id="content", class="showtxt").get_text()
優化為:
tt = soup.find('div', id="content", class_="showtxt").text.replace(' ','n').replace('app2();','n')
即將app2()和空格符都替換為換行符。運行后得到效果為:
圖3-9 優化后最終的爬取結果
至此,一個簡單的爬取就完成了。
其實,該網址內容完全可以直接復制就能得到,本文之所以還大費周章進行爬取,不過是借用這個簡單的靜態網頁,體驗一下爬蟲4步驟的流程,為后續批量爬取網頁中的小說、圖片以及爬取動態網頁數據做基礎。
4、附錄本文代碼(完整)
# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
# 第一步:發出訪問請求
url = "https://www.biqiuge.com/book/4772/2940354.html"
response = requests.get(url)
# 第二步:獲得網頁信息
soup = BeautifulSoup(response.content, 'lxml')
# 第三步:解析網頁數據
t1 = soup.find('a', href="/book/4772/").get_text()
t2 = soup.find('h1').get_text()
tt = soup.find('div', id="content", class_="showtxt").text.replace(' ','n').replace('app2();','n')
# 第四步:保存內容
f = open(r"e:小說1.txt", 'a+', encoding='utf-8')
f.write(t1 + 'n')
f.write(t2 + 'n')
f.write(tt)
f.close()
print('下載完成')