最近在学习Python,相对java来说python简单易学、语法简单,工具丰富,开箱即用,适用面广做全栈开发那是极好的,对于小型应用的开发,虽然运行效率慢点,但开发效率极高。大大提高了咱们的生产力。为什么python能够在这几年火起来,自然有他的道理,当然也受益于这几年大数据和AI的火。 据说网络上80的爬虫都是用python写的,不得不说python写爬虫真的是soeasy。基本上一个不太复杂的网站可以通过python用100多行代码就能实现你所需要的爬取。 现在就以一个电子书的网站为例来实现python爬虫获取电子书资源。爬取整站的电子书资源,按目录保存到本地,并形成索引文件方便查找。 爬取的目标网站:苦瓜书盘步骤:爬取分析、解析保存 对于一个不需要登录验证的资源分享类的网站,爬取最大的工作量应该是在对目标页面的分析、解析、识别,这里用的到是Python的BeautifulSoup库。 一、获取目录 二、获取书籍列表页 三、获取书籍详情页 四、分析书籍详情页的资源地址 五、下载并保存准备 引入相应的包,设置headerd,和资源保存路径importrequestsimportosimportrefrombs4importBeautifulSoupimporttimeimportjsonfromBookimportBooksavepathJ:kgbookbooks保存地址headers{UserAgent:Mozilla5。0(MIntelMacOSX10114)AppleWebKit537。36(KHTML,likeGecko)Chrome52。0。2743。116Safari537。36}mainurlhttps:kgbook。combookcount0一、获取目录 通过浏览器的调试工具可以看到目录在idcatagory的p标签下,下面还有ul和li标签,那我们可以迭代li可以获得目录及目录页的地址。 可以通过soup。findall(attrs{‘id’:‘category’})〔0〕。ul获取到ul标签,然后获取ul的li标签,进行迭代获取。 代码如下:获取目录defgetcategory():reqresultrequests。get(mainurl,headersheaders)ifreqresult。statuscode200:htmlstrreqresult。content。decode(utf8)soupBeautifulSoup(htmlstr,lxml)categoryssoup。findall(attrs{id:category})〔0〕。ulforliincategorys。findall(nameli):print(开始抓取li。a。attrs〔href〕li。string)getcategroydetail(mainurlli。a。attrs〔href〕,li。string)time。sleep(1)二、获取书籍列表页 在书籍列表页,我们要获取两个信息,分别是书籍列表的信息及翻页下一页书籍列表的URL地址。 通过浏览器的调试工具分别对列表的信息及翻页下一页的html进行分析。 列表中的书籍详情页信息在classchannelitem的p标签下,通过classlisttitle的h3标签循环迭代 下一页,我们可以直接通过nextpagsoup。find(name’a’,textre。compile(‘下一页’))来获取。 然后我们可以通过递归来不断地调用获取下一页书籍列表页的代码,知道没有下一页为止。就可以把整个目录都可以爬取完。 代码如下:获取书籍列表defgetbookslist(bookurlstr,categroypath):bookresultrequests。get(bookurlstr,headersheaders)bookhtmlstrbookresult。content。decode(utf8)soupBeautifulSoup(bookhtmlstr,lxml)booklistssoup。select(。channelitem)forbookinfopinbooklists:booktitlepbookinfop。select(。listtitle)〔0〕bookurlbooktitlep。a。attrs〔href〕getbookdetail(bookurl,categroypath)nextpagsoup。find(namea,textre。compile(下一页))ifnextpagisnotNone:nexturlnextpag。attrs〔href〕print(爬取下一页:nexturl)getbookslist(nexturl,categroypath)三、获取书籍详情页 我们要在书籍详情页需要获得书籍详情信息包括书名、作者等信息 关于书名和作者可以分别通过提取classnewstitle的h1标签和idnewsdetails的p下的ul下的li再通过正则表达式对作者信息进行提取。booktitlebookdetailsoup。select(。newstitle)〔0〕。text。strip()bookauthorbookdetailsoup。select(newsdetails)〔0〕。ul。li。find(textre。compile(作者:(。?)))。strip()bookauthorbookauthor。replace(作者:,)booktitleinfo《booktitle》bookauthor四、分析书籍详情页的资源地址 在书籍详情页,我们还要分析书籍详情页的资源地址 电子书的资源下载地址可以通过提取a标签的信息来获取。通过正则表达式分别匹配azw3、mobi、epub分别提取不同的电子书资源。 bookurlitembookdetailsoup。find(name’a’,textre。compile(booktype,re。I)) 代码如下:根据书籍资源类型下载资源defgetbookfortype(bookurl,categroypath,bookdetailsoup,booktype):booktitlebookdetailsoup。select(。newstitle)〔0〕。text。strip()bookauthorbookdetailsoup。select(newsdetails)〔0〕。ul。li。find(textre。compile(作者:(。?)))。strip()bookauthorbookauthor。replace(作者:,)booktitleinfo《booktitle》bookauthorprint(书籍详情:booktitleinfo)bookurlitembookdetailsoup。find(namea,textre。compile(booktype,re。I))ifbookurlitemisnotNone:downloadurlbookurlitem。attrs〔href〕print(下载地址:downloadurl)ifcheckIfNoExistBookByUrl(downloadurl):rrequests。get(downloadurl)ifr。statuscode200:savepathcreatedir(categroypath,booktitleinfo)filenamebooktitle。booktypesavebook(r。content,savepath,filename)p,fos。path。split(categroypath)bookcategoryfbookBook(bookcategory,booktitle,bookauthor,bookurl,downloadurl,savepath,苦瓜书盘,booktype)print(book。toString())savebooktojson(book)else:print(下载失败:statuscodestr(r。statuscode))else:print(没有booktype格式的书) 五、下载并保存 有了资源的下载资源后下载就变得很简单了,主要用python的os库,对文件进行操作,包括建目录及保存资源文件。也可以通过连接数据库将爬取的数据保存到数据库。 定义书籍类Book用于组织和保存数据。classBook(object):definit(self,bookcategory,bookname,bookauthor,bookurl,bookdownloadurl,booksavepath,booksource,booktype):self。bookcategorybookcategoryself。booknamebooknameself。bookauthorbookauthorself。bookurlbookurlself。bookdownloadurlbookdownloadurlself。booksavepathbooksavepathself。booksourcebooksourceself。booktypebooktypedeftoString(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}将获取的信息保存至文件defsavebooktojson(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}bookjsonjson。dumps(bookdata,ensureasciiFalse)ensureasciiFalse就不会用ASCII编码,中文就可以正常显示了print(bookjson)withopen(data。json,a,encodinggbk)asfile:file。write(bookjson)根据目录创建文件夹defcreatedir(savepath,dir):pathos。path。join(savepath,dir)isExistsos。path。exists(path)ifisExists:print(已经存在dir)else:print(创建目录dir)os。mkdir(path)returnpath下载书籍资源defsavebook(content,savepath,savefilename):savefileos。path。join(savepath,savefilename)withopen(savefile,wb)ascode:code。write(content) 运行效果如下: 1、爬取过程 2、爬取记录的json信息 data。json的信息如下: 3、爬取获取的资源 按目录都已经整理好了,够你看的了。