最近在學習Python,相對java來說python簡單易學、語法簡單,工具豐富,開箱即用,適用面廣做全棧開發那是極好的,對於小型應用的開發,雖然運行效率慢點,但開發效率極高。大大提高了咱們的生產力。為什么python能夠在這幾年火起來,自然有他的道理,當然也受益於這幾天大數據和AI的火。
據說網絡上80%的爬蟲都是用python寫的,不得不說python寫爬蟲真的是so easy。基本上一個不太復雜的網站可以通過python用100多行代碼就能實現你所需要的爬取。 現在就以一個電子書的網站為例來實現python爬蟲獲取電子書資源。爬取整站的電子書資源,按目錄保存到本地,並形成索引文件方便查找。
爬取的目標網站:苦瓜書盤
步驟:爬取->分析、解析->保存
對於一個不需要登錄驗證的資源分享類的網站,爬取最大的工作量應該是在對目標頁面的分析、解析、識別,這里用的到是Python的BeautifulSoup庫。
一、獲取目錄
二、獲取書籍列表頁
三、獲取書籍詳情頁
四、分析書籍詳情頁的資源地址
五、下載並保存
一、獲取目錄

通過瀏覽器的調試工具可以看到目錄在id=catagory的div標簽下,下面還有ul和li標簽,那我們可以迭代li可以獲得目錄及目錄頁的地址。
可以通過soup.find_all( attrs ={ 'id' : 'category' })[ 0 ].ul 獲取 到ul標簽,然后獲取ul的li標簽,進行迭代獲取。
代碼如下:
'''
獲取目錄
'''
def getcategory():
req_result=requests.get(main_url, headers =headers)
if req_result.status_code== 200 :
htmlstr=req_result.content.decode( 'utf-8' )
soup = BeautifulSoup(htmlstr, 'lxml' )
categorys=soup.find_all( attrs ={ 'id' : 'category' })[ 0 ].ul
for li in categorys.find_all( name = 'li' ):
print ( '開始抓取' +li.a.attrs[ 'href' ]+ "--" +li.string)
getcategroydetail(main_url+li.a.attrs[ 'href' ],li.string)
time.sleep( 1 )
二、獲取書籍列表頁
在書籍列表頁,我們要獲取兩個信息,分別是書籍列表的信息及翻頁下一頁書籍列表的URL地址。
通過瀏覽器的調試工具分別對列表的信息及翻頁下一頁的html進行分析。

列表中的書籍詳情頁信息在class="channel-item"的div標簽下,通過class="list-title"的h3標簽循環迭代

下一頁,我們可以直接通過next_pag=soup.find(name='a',text=re.compile('下一頁'))來獲取。
然后我們可以通過遞歸來不斷的調用獲取下一頁書籍列表頁的代碼,知道沒有下一頁為止。就可以把怎個目錄都可以爬取完。
代碼如下:
'''
獲取書籍列表
'''
def getbookslist(bookurlstr,categroy_path):
book_result=requests.get(bookurlstr, headers =headers)
bookhtmlstr=book_result.content.decode( 'utf-8' )
soup = BeautifulSoup(bookhtmlstr, 'lxml' )
booklists=soup.select( '.channel-item' )
for bookinfo_div in booklists:
booktitle_div=bookinfo_div.select( '.list-title' )[ 0 ]
bookurl=booktitle_div.a.attrs[ 'href' ]
getbookdetail(bookurl,categroy_path)
next_pag=soup.find( name = 'a' , text =re.compile( '下一頁' ))
if next_pag is not None :
next_url=next_pag.attrs[ 'href' ]
print ( '爬取下一頁:' +next_url)
getbookslist(next_url,categroy_path)
三、獲取書籍詳情頁
我們要在書籍詳情頁需要獲得書籍詳情信息包括書名、作者等信息

關於書名和作者可以分別通過提取class="news_title"的h1標簽和id="news_details"的div下的ul下的li再通過正則表達式對作者信息進行提取。
booktitle=bookdetailsoup.select( '.news_title' )[ 0 ].text.strip()
bookauthor=bookdetailsoup.select( '#news_details' )[ 0 ].ul.li.find( text =re.compile( '作者:(.*?)' )).strip()
bookauthor=bookauthor.replace( '作者:' , '' )
booktitleinfo= "《" +booktitle+ '》-' +bookauthor
四、分析書籍詳情頁的資源地址
在書籍詳情頁,我們還要分析書籍詳情頁的資源地址

電子書的資源下載地址可以通過提取a標簽的信息來獲取。通過正則表達式分別匹配azw3、mobi、epub分別提取不同的電子書資源。
book_url_item=bookdetailsoup.find( name = 'a' , text =re.compile(booktype,re.I))
代碼如下:
'''
根據書籍資源類型下載資源
'''
def getbookfortype(bookurl,categroy_path,bookdetailsoup,booktype):
booktitle=bookdetailsoup.select( '.news_title' )[ 0 ].text.strip()
bookauthor=bookdetailsoup.select( '#news_details' )[ 0 ].ul.li.find( text =re.compile( '作者:(.*?)' )).strip()
bookauthor=bookauthor.replace( '作者:' , '' )
booktitleinfo= "《" +booktitle+ '》-' +bookauthor
print ( '書籍詳情:---' +booktitleinfo)
book_url_item=bookdetailsoup.find( name = 'a' , text =re.compile(booktype,re.I))
if book_url_item is not None :
downloadurl=book_url_item.attrs[ 'href' ]
print ( '下載地址:' +downloadurl)
if checkIfNoExistBookByUrl(downloadurl):
r = requests.get(downloadurl)
if r.status_code== 200 :
savepath=createdir(categroy_path,booktitleinfo)
filename=booktitle+ "." +booktype
savebook(r.content,savepath,filename)
p,f=os.path.split(categroy_path)
bookcategory=f
book=Book(bookcategory,booktitle,bookauthor,bookurl,downloadurl,savepath, "苦瓜書盤" ,booktype)
print (book.toString())
savebooktojson(book)
else :
print ( '下載失敗:status_code=' + str (r.status_code))
else :
print ( '沒有' +booktype+ '格式的書' )
五、下載並保存
有了資源的下載資源后下載就變得很簡單了,主要用python的os庫,對文件進行操作,包括建目錄及保存資源文件。也可以通過連接數據庫將爬取的數據保存到數據庫。
定義書籍類Book用於組織和保存數據。
class Book( object ):
def __init__ ( self ,bookcategory,bookname,bookauthor,bookurl,bookdownloadurl,booksavepath,booksource,booktype):
self .bookcategory=bookcategory
self .bookname=bookname
self .bookauthor=bookauthor
self .bookurl=bookurl
self .bookdownloadurl=bookdownloadurl
self .booksavepath=booksavepath
self .booksource=booksource
self .booktype=booktype
def toString( self ):
return { "bookcategory" : self .bookcategory, "bookname" : self .bookname, "bookauthor" : self .bookauthor, "bookurl" : self .bookurl, "bookdownloadurl" : self .bookdownloadurl, "booksavepath" : self .booksavepath, "booksource" : self .booksource, "booktype" : self .booktype}
'''
將獲取的信息保存至文件
'''
def savebooktojson(book):
bookdata={
'booksource' :book.booksource,
'booktype' :book.booktype,
'bookcategory' :book.bookcategory,
'bookname' :book.bookname,
'bookauthor' :book.bookauthor,
'bookurl' :book.bookurl,
'bookdownloadurl' :book.bookdownloadurl,
'booksavepath' :book.booksavepath
}
bookjson=json.dumps(bookdata, ensure_ascii = False ) #ensure_ascii=False 就不會用 ASCII 編碼,中文就可以正常顯示了
print (bookjson)
with open ( 'data.json' , 'a' , encoding = 'gbk' ) as file:
file.write(bookjson+ ' \n ' )
'''
根據目錄創建文件夾
'''
def createdir(savepath,dir):
path=os.path.join(savepath,dir)
isExists=os.path.exists(path)
if isExists:
print ( '已經存在' +dir)
else :
print ( '創建目錄' +dir)
os.mkdir(path)
return path
'''
下載書籍資源
'''
def savebook(content,savepath,savefilename):
savefile=os.path.join(savepath,savefilename)
with open (savefile, "wb" ) as code:
code.write(content)
---------------------------------------------------------
運行效果如下:
1、爬取過程

2、爬取記錄的json信息
data.json的信息如下:

3、爬取獲取的資源
按目錄都已經整理好了,夠你看的了。

Python爬蟲獲取電子書資源實戰的全部代碼,包括爬取->分析、解析->保存至本地及數據庫。
此文轉載文,著作權歸作者所有,如有侵權聯系小編刪除!
原文地址:https://blog.csdn.net/fullbug/article/details/80631263