[爬虫系列(二)]爬取豆瓣读书Top250,并保存每本书

这里我们要爬起豆瓣读书Top250,并保存每本书的书名,信息,简要介绍和作者信息.
这里,仍然分为三步:
1.url分析
2.数据分析
3.爬取数据

1.url分析

豆瓣读书Top250的url分析和豆瓣电影Top250类似:
豆瓣读书Top250的url基本都是这样的:

http://book.douban.com/top250?start=

所以,同样我也是利用urlparse的urljoin函数来拼接自己所需要的url,传入urlopen()

2.数据分析

利用urlopen,我们得到response对象,接着传入BeautifulSoup得到BeautifulSoup对象.接下来便分析数据了.
查看源代码,我们发现每本书的名字都包含在具有title属性的a标签中,同时令我们惊喜的时,a标签中还有href属性,这样我们就可以直接获取这本书的名字和它所对应豆瓣网页,为我们接下来获取这本书的详细介绍打下基础.
[爬虫系列(二)]爬取豆瓣读书Top250,并保存每本书_第1张图片
于是,我们可以利用find_all()函数来查找所有具有title属性的a标签.同样,在这里find_all()函数也是在html文档树中从上到下查找,所以我们也不需要担心Top顺序,找到之后,我们还可以判断a标签是否含有href属性,如果有的话,就可以提取href属性对应的url来获取这本书的详细介绍了

代码介绍

在我的代码里,我主要声明了两个函数,Parse_Page()和Parse_Book().Parse_Page()负责上面的工作:找到所有的符合要求的a标签,提取对应的url,然后将该url传入给Parse_Book().Parse_Book()则负责处理url,爬取每本书的具体数据.可以说Parse_Page()和Parse_Book()这两个函数业务都比较清晰的,而且也不是很难.
下面说说Parse_Book()是如何工作的:

book_bsObj=BeautifulSoup(response,"lxml")
            book_title=book_bsObj.h1
            book_info=book_bsObj.find("div",{"id":"info"})
            intro=book_bsObj.find_all("div",{"class":"intro"})

book_title和book_info对应书的名字和信息.但是,因为书籍简介和作者信息都是对应在相同标签中:即具有class=intro的div标签中.所以暂时无法区分这两个,只好先把全部具有class=intro的div标签找到.
但是,找到intro后,不能认为书籍介绍就是对应的是intro[0],而作者信息就是对应的是intro[1].
比如,对红楼梦这本书来说,如果我们得到intro,并打印intro[0],那么我们得到的是下面这个内容:
[爬虫系列(二)]爬取豆瓣读书Top250,并保存每本书_第2张图片
那如果我们打印intro[1],又是什么情况呢?答案是这样:
[爬虫系列(二)]爬取豆瓣读书Top250,并保存每本书_第3张图片
有什么区别呢?实际上intro[1]对应的是intro[0]展开全部的内容,即我们在豆瓣网页点击展开全部得到的内容.为什么会这样呢?因为在豆瓣网页里,展开全部有js交互,所以intro[1]对应的就是intro[0]展开全部的内容了.那么,利用这一特点,我们也可以取巧.可以不与js交互,而是判断当前文本是否含有展开全部这四个子;如果有,说明下一个元素才是我们需要的详细文本,如果没有,说明当前就是完整的文本了.这一特点同样也适用作者信息的提取
判断代码在此:
if intro[0].get_text().encode('utf-8').find('展开全部')!=-1:
book_intro=intro[1]
if intro[2].get_text().encode('utf-8').find('展开全部')!=-1:
author_intro=intro[3]
else:
author_intro=intro[2]
else:
book_intro=intro[0]
if intro[1].get_text().encode('utf-8').find('展开全部')!=-1:
author_intro=intro[2]
else:
author_intro=intro[1]

3.爬取数据

数据分析完成后,那么接下来爬取数据,写入文本都是很容易的事了.

最后,爬取数据在此

源代码在此

你可能感兴趣的:(python,爬虫)