Python3網路爬蟲:使用Beautiful Soup爬取小說
本文是http://blog.csdn.net/c406495762/article/details/71158264的學習筆記
作者:Jack-Cui
博主連結:http://blog.csdn.net/c406495762
執行平臺: OSX
Python版本: Python3.x
IDE: pycharm
一、Beautiful Soup簡介
簡單來說,Beautiful Soup是python的一個庫,最主要的功能是從網頁抓取資料。官方解釋如下:
Beautiful Soup提供一些簡單的、python式的函式用來處理導航、搜尋、修改分析樹等功能。它是一個工具箱,通過解析文件為使用者提供需要抓取的資料,因為簡單,所以不需要多少程式碼就可以寫出一個完整的應用程式。
Beautiful Soup自動將輸入文件轉換為Unicode編碼,輸出文件轉換為utf-8編碼。你不需要考慮編碼方式,除非文件沒有指定一個編碼方式,這時,Beautiful Soup就不能自動識別編碼方式了。然後,你僅僅需要說明一下原始編碼方式就可以了。
Beautiful Soup已成為和lxml、html6lib一樣出色的python直譯器,為使用者靈活地提供不同的解析策略或強勁的速度。
二、Beautiful Soup學習
在這裡推薦 Python爬蟲利器二之Beautiful Soup的用法 ,和官方文件相似,但是內容作了精簡.
另附上 官方文件
三、實戰
小說網站-筆趣看:
URL:http://www.biqukan.com/
以該小說網為例,爬取《神墓》
整體思路:
1. 選擇神墓小說某一章節,檢查,找到正文部分的TAG
2. 嘗試使用BeautifulSoup打印出該章節正文部分內容
3. 從索引爬取全部的章節的url,用for迴圈列印
4. 結合3、2並將2的列印部分換成寫入檔案
具體步驟:
1. 選擇《神墓》小說第一章,檢查,找到正文部分的html標籤
連結url:http://www.biqukan.com/3_3039/1351331.html
發現小說正文部分所在標籤是:
<div id='content' class='showtxt'>正文部分</div>
2. 嘗試使用BeautifulSoup打印出該章節正文部分內容
from urllib import request
from bs4 import BeautifulSoup
import os
def download_specified_chapter(chapter_url,header,coding,chapter_name=None):
#先生成一個request物件,傳入url和headers
download_req = request.Request(chapter_url,headers=header)
#通過指定urlopen開啟request物件中的url網址,並獲得對應內容
response = request.urlopen(download_req)
#獲取頁面的html
download_html = response.read().decode(coding, 'ignore')
#獲取html的bs
origin_soup = BeautifulSoup(download_html, 'lxml')
#獲取小說正文部分
content=origin_soup.find(id='content', class_='showtxt')
#經列印,發現文字中有眾多的\xa0(在html中是 ),並且沒有換行,
print(repr(content.text))
#整理小說格式,將\xa0替換成回車
# html中的 ,在轉換成文件後,變成\xa0
txt=content.text.replace('\xa0'*8,'\n')
print(txt)
if __name__=="__main__":
target_url='http://www.biqukan.com/3_3039/1351331.html'
header = {
'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'
}
download_specified_chapter(target_url,header,'gbk')
結果如圖:
3. 從索引爬取全部的章節的url,用for迴圈列印
索引的url:http://www.biqukan.com/3_3039/
檢查後發現
我們所需要的章節的url,在<div class="lsitmain">
下的<dl>
下的<dd>
中的<a>
標籤中,並且是在<dt>《神墓》正文卷</dt>
之後.
嘗試用for迴圈列印:
from urllib import request
from bs4 import BeautifulSoup
if __name__ == "__main__":
index_url = "http://www.biqukan.com/3_3039/"
header={
'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'
}
#指定url,header生成request
url_req = request.Request(index_url,headers=header)
#開啟url,並獲得請求內容response
response = request.urlopen(url_req)
#讀取response的內容,用gbk解碼,得到html內容
html = response.read().decode('gbk', 'ignore')
#用BeautifulSoup處理得到的網頁html
html_soup = BeautifulSoup(html,'lxml')
# index = BeautifulSoup(str(html_soup.find_all('div', class_='listmain')),'lxml')
# print(html_soup.find_all(['dd', ['dt']]))
#判斷是否找到了《神墓》正文卷
body_flag = False for element in html_soup.find_all(['dd', ['dt']]):
if element.string == '《神墓》正文卷':
body_flag = True
if body_flag is True and element.name == 'dd':
chapter_name = element.string
chapter_url = "http://www.biqukan.com"+element.a.get('href')
print(" {} 連結:{}".format(chapter_name,chapter_url))
執行結果:
4.結合3、2並將2的列印部分換成寫入檔案
由步驟3 獲得章節的url,再由步驟2 根據url,獲得正文部分,兩相結合,再不斷地將內容寫入檔案中.
程式碼如下:
from urllib import request
from bs4 import BeautifulSoup
def download_specified_chapter(chapter_url, header, coding, chapter_name=None):
#先生成一個request物件,傳入url和headers
download_req = request.Request(chapter_url,headers=header)
#通過指定urlopen開啟request物件中的url網址,並獲得對應內容
response = request.urlopen(download_req)
#獲取頁面的html
download_html = response.read().decode(coding, 'ignore')
#獲取html的bs
origin_soup = BeautifulSoup(download_html, 'lxml')
#獲取小說正文部分
content=origin_soup.find(id='content', class_='showtxt')
#整理小說格式,將\xa0替換成回車
# html中的 ,在轉換成文件後,變成\xa0
txt=content.text.replace('\xa0'*8,'\n')
# 將獲得的正文 寫入txt
print("正在下載 {} 連結:{}".format(chapter_name,chapter_url))
with open('《神墓》.txt','a') as f:
if chapter_name is None:
f.write('\n')
else :
f.write('\n'+chapter_name+'\n')
f.write(txt)
if __name__ == "__main__":
index_url = "http://www.biqukan.com/3_3039/"
header={
'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'
}
#指定url,header生成request
url_req = request.Request(index_url,headers=header)
#開啟url,並獲得請求內容response
response = request.urlopen(url_req)
#讀取response的內容,用gbk解碼,得到html內容
html = response.read().decode('gbk', 'ignore')
#用BeautifulSoup處理得到的網頁html
html_soup = BeautifulSoup(html,'lxml')
# index = BeautifulSoup(str(html_soup.find_all('div', class_='listmain')),'lxml')
# print(html_soup.find_all(['dd', ['dt']]))
#判斷是否找到了《神墓》正文卷
body_flag = False
for element in html_soup.find_all(['dd', ['dt']]):
if element.string == '《神墓》正文卷':
body_flag = True
#從《神墓》正文卷 之後的dd就是順序的章節目錄
if body_flag is True and element.name == 'dd':
chapter_name = element.string
chapter_url = "http://www.biqukan.com"+element.a.get('href')
download_specified_chapter(chapter_url, header, 'gbk', chapter_name)
結果如圖:
txt截圖:
這樣就大功告成 ^_^