继爬取 猫眼电影TOP100榜单 之后,再来爬一下豆瓣的书籍信息(主要是书的信息,评分及占比,评论并未爬取)。原创,转载请联系我。

需求:爬取豆瓣某类型标签下的所有书籍的详细信息及评分

语言:python

支持库:

正则、解析和搜索:re、requests、bs4、lxml (后三者需要安装)

随机数:time、random

步骤:三步走

访问标签页面,获取该标签下的所有书籍的链接

逐一访问书籍链接,爬取书籍信息和评分

持久化存储书籍信息(这里用了excel,可以使用数据库)

一、访问标签页面,获取该标签下的所有书籍的链接

照例,我们先看一下豆瓣的Robots.txt , 不能爬取禁止的内容。

先去看看它的HTML结构

发现,每一本书,都在一个

标签当中,而我们需要的只是那张图片的链接(就是书籍页面的链接)

这样,就可以写正则或者是利用bs4(BeatuifulSoup)来获取书籍的链接。

可以看到,每一页只显示了20本书,所以需要遍历访问所有的页面,它的页面链接也是有规律的。

即:start每次递增20就好了。

下面来看代码:

1 #-*- coding: utf-8 -*-

2 #@Author : yocichen

3 #@Email : yocichen@126.com

4 #@File : labelListBooks.py

5 #@Software: PyCharm

6 #@Time : 2019/11/11 20:10

7

8 importre9 importopenpyxl10 importrequests11 from requests importRequestException12 from bs4 importBeautifulSoup13 importlxml14 importtime15 importrandom16

17 src_list =[]18

19 defget_one_page(url):20 '''

21 Get the html of a page by requests module22 :param url: page url23 :return: html / None24 '''

25 try:26 head = ['Mozilla/5.0', 'Chrome/78.0.3904.97', 'Safari/537.36']27 headers ={28 'user-agent':head[random.randint(0, 2)]29 }30 response = requests.get(url, headers=headers, proxies={'http':'171.15.65.195:9999'}) # 这里的代理,可以设置也可以不加,如果失效,不加或者替换其他的即可31 if response.status_code == 200:32 returnresponse.text33 returnNone34 exceptRequestException:35 returnNone36

37 defget_page_src(html, selector):38 '''

39 Get book's src from label page40 :param html: book41 :param selector: src selector42 :return: src(list)43 '''

44 #html = get_one_page(url)

45 if html is notNone:46 soup = BeautifulSoup(html, 'lxml')47 res =soup.select(selector)48 pattern = re.compile('href="(.*?)"', re.S)49 src =re.findall(pattern, str(res))50 returnsrc51 else:52 return[]53

54 defwrite_excel_xlsx(items, file):55 '''

56 Write the useful info into excel(*.xlsx file)57 :param items: book's info58 :param file: memory excel file59 :return: the num of successful item60 '''

61 wb =openpyxl.load_workbook(file)62 ws =wb.worksheets[0]63 sheet_row =ws.max_row64 item_num =len(items)65 #Write film's info

66 for i inrange(0, item_num):67 ws.cell(sheet_row+i+1, 1).value =items[i]68 #Save the work book as *.xlsx

69 wb.save(file)70 returnitem_num71

72 if __name__ == '__main__':73 total =074 for page_index in range(0, 50): # 这里为什么是50页?豆瓣看起来有很多页,其实访问到后面就没有数据了,目前是只有50页可访问。75 #novel label src : https://book.douban.com/tag/%E5%B0%8F%E8%AF%B4?start=

76 #program label src : https://book.douban.com/tag/%E7%BC%96%E7%A8%8B?start=

77 #computer label src : https://book.douban.com/tag/%E8%AE%A1%E7%AE%97%E6%9C%BA?start=

78 #masterpiece label src : https://book.douban.com/tag/%E5%90%8D%E8%91%97?start=

79 url = 'https://book.douban.com/tag/%E5%90%8D%E8%91%97?start='+str(page_index*20)+'&type=T' # 你要做的就是把URL前面的部分替换成你所有爬的那个标签的对应部分,确切的来说是红色加粗的文字部分。

80 one_loop_done =081 #only get html page once

82 html =get_one_page(url)83 for book_index in range(1, 21):84 selector = '#subject_list > ul > li:nth-child('+str(book_index)+') > div.info > h2'

85 src =get_page_src(html, selector)86 row = write_excel_xlsx(src, 'masterpiece_books_src.xlsx') # 要存储的文件,需要先创建好87 one_loop_done +=row88 total +=one_loop_done89 print(one_loop_done, 'done')90 print('Total', total, 'done')

注释比较清楚了,先获取页面HTML,正则或者bs4遍历获取每一页当中的书籍链接,存到excel文件中。

注意:如果需要直接使用我的代码,你只需要去看一下那个标签页面的链接,而后把红色加粗部分(中文标签编码)替换即可,以及先创建一个excel文件,用以存储爬到的书籍链接。

二、逐一访问书籍链接,爬取书籍信息和评分

上一步我们已经爬到了,小说标签下的所有书籍的src,这一步,就是要逐一去访问书籍的src,然后爬取书籍的具体信息。

先看看要爬的信息的HTML结构

下面是书籍信息页面结构

再是评分页面结构

这样就可以利用正则表达式和bs4库来匹配到我们所需要的数据了。(试了试纯正则,比较难写,行不通)

下面看代码

1 #-*- coding: utf-8 -*-

2 #@Author : yocichen

3 #@Email : yocichen@126.com

4 #@File : doubanBooks.py

5 #@Software: PyCharm

6 #@Time : 2019/11/9 11:38

7

8 importre9 importopenpyxl10 importrequests11 from requests importRequestException12 from bs4 importBeautifulSoup13 importlxml14 importtime15 importrandom16

17 defget_one_page(url):18 '''

19 Get the html of a page by requests module20 :param url: page url21 :return: html / None22 '''

23 try:24 head = ['Mozilla/5.0', 'Chrome/78.0.3904.97', 'Safari/537.36']25 headers ={26 'user-agent':head[random.randint(0, 2)]27 }28 response = requests.get(url, headers=headers) #, proxies={'http':'171.15.65.195:9999'}

29 if response.status_code == 200:30 returnresponse.text31 returnNone32 exceptRequestException:33 returnNone34

35 defget_request_res(pattern_text, html):36 '''

37 Get the book info by re module38 :param pattern_text: re pattern39 :param html: page's html text40 :return: book's info41 '''

42 pattern =re.compile(pattern_text, re.S)43 res =re.findall(pattern, html)44 if len(res) >0:45 return res[0].split('<', 1)[0][1:]46 else:47 return 'NULL'

48

49 defget_bs_res(selector, html):50 '''

51 Get the book info by bs4 module52 :param selector: info selector53 :param html: page's html text54 :return: book's info55 '''

56 soup = BeautifulSoup(html, 'lxml')57 res =soup.select(selector)58 #if res is not None or len(res) is not 0:

59 #return res[0].string

60 #else:

61 #return 'NULL'

62 if res isNone:63 return 'NULL'

64 elif len(res) ==0:65 return 'NULL'

66 else:67 returnres[0].string68

69 #Get other info by bs module

70 defget_bs_img_res(selector, html):71 soup = BeautifulSoup(html, 'lxml')72 res =soup.select(selector)73 if len(res) is not0:74 returnstr(res[0])75 else:76 return 'NULL'

77

78 defparse_one_page(html):79 '''

80 Parse the useful info of html by re module81 :param html: page's html text82 :return: all of book info(dict)83 '''

84 book_info ={}85 book_name = get_bs_res('div > h1 > span', html)86 #print('Book-name', book_name)

87 book_info['Book_name'] =book_name88 #info > a:nth-child(2)

89 author = get_bs_res('div > span:nth-child(1) > a', html)90 if author isNone:91 author = get_bs_res('#info > a:nth-child(2)', html)92 #print('Author', author)

93 author = author.replace(" ", "")94 author = author.replace("\n", "")95 book_info['Author'] =author96

97 publisher = get_request_res(u'出版社:(.*?)
', html)98 #print('Publisher', publisher)

99 book_info['publisher'] =publisher100

101 publish_time = get_request_res(u'出版年:(.*?)
', html)102 #print('Publish-time', publish_time)

103 book_info['publish_time'] =publish_time104

105 ISBN = get_request_res(u'ISBN:(.*?)
', html)106 #print('ISBN', ISBN)

107 book_info['ISBN'] =ISBN108

109 img_label = get_bs_img_res('#mainpic > a > img', html)110 pattern = re.compile('src="(.*?)"', re.S)111 img =re.findall(pattern, img_label)112 if len(img) is not0:113 #print('img-src', img[0])

114 book_info['img_src'] =img[0]115 else:116 #print('src not found')

117 book_info['img_src'] = 'NULL'

118

119 book_intro = get_bs_res('#link-report > div:nth-child(1) > div > p', html)120 #print('book introduction', book_intro)

121 book_info['book_intro'] =book_intro122

123 author_intro = get_bs_res('#content > div > div.article > div.related_info > div:nth-child(4) > div > div > p', html)124 #print('author introduction', author_intro)

125 book_info['author_intro'] =author_intro126

127 grade = get_bs_res('div > div.rating_self.clearfix > strong', html)128 if len(grade) == 1:129 #print('Score no mark')

130 book_info['Score'] = 'NULL'

131 else:132 #print('Score', grade[1:])

133 book_info['Score'] = grade[1:]134

135 comment_num = get_bs_res('#interest_sectl > div > div.rating_self.clearfix > div > div.rating_sum > span > a > span', html)136 #print('commments', comment_num)

137 book_info['commments'] =comment_num138

139 five_stars = get_bs_res('#interest_sectl > div > span:nth-child(5)', html)140 #print('5-stars', five_stars)

141 book_info['5_stars'] =five_stars142

143 four_stars = get_bs_res('#interest_sectl > div > span:nth-child(9)', html)144 #print('4-stars', four_stars)

145 book_info['4_stars'] =four_stars146

147 three_stars = get_bs_res('#interest_sectl > div > span:nth-child(13)', html)148 #print('3-stars', three_stars)

149 book_info['3_stars'] =three_stars150

151 two_stars = get_bs_res('#interest_sectl > div > span:nth-child(17)', html)152 #print('2-stars', two_stars)

153 book_info['2_stars'] =two_stars154

155 one_stars = get_bs_res('#interest_sectl > div > span:nth-child(21)', html)156 #print('1-stars', one_stars)

157 book_info['1_stars'] =one_stars158

159 returnbook_info160

161 defwrite_bookinfo_excel(book_info, file):162 '''

163 Write book info into excel file164 :param book_info: a dict165 :param file: memory excel file166 :return: the num of successful item167 '''

168 wb =openpyxl.load_workbook(file)169 ws =wb.worksheets[0]170 sheet_row =ws.max_row171 sheet_col =ws.max_column172 i =sheet_row173 j = 1

174 for key inbook_info:175 ws.cell(i+1, j).value =book_info[key]176 j += 1

177 done = ws.max_row -sheet_row178 wb.save(file)179 returndone180

181 defread_booksrc_get_info(src_file, info_file):182 '''

183 Read the src file and access each src, parse html and write info into file184 :param src_file: src file185 :param info_file: memory file186 :return: the num of successful item187 '''

188 wb =openpyxl.load_workbook(src_file)189 ws =wb.worksheets[0]190 row =ws.max_row191 done =0192 for i in range(868, row+1):193 src = ws.cell(i, 1).value194 if src isNone:195 continue

196 html =get_one_page(str(src))197 book_info =parse_one_page(html)198 done +=write_bookinfo_excel(book_info, info_file)199 if done % 10 ==0:200 print(done, 'done')201 returndone202

203 if __name__ == '__main__':204 #url = 'https://book.douban.com/subject/1770782/'

205 #html = get_one_page(url)

206 ## print(html)

207 #book_info = parse_one_page(html)

208 #print(book_info)

209 #res = write_bookinfo_excel(book_info, 'novel_books_info.xlsx')

210 #print(res, 'done')

211 res = read_booksrc_get_info('masterpiece_books_src.xlsx', 'masterpiece_books_info.xlsx') # 读取的src文件,要写入书籍信息的存储文件212 print(res, 'done')

注意:如果要直接使用的话,需要做的只是给参数而已,第一个是上一步获取的src文件,第二个是需要存储书籍信息的文件(需要事先创建一下)

三、持久化存储书籍信息(Excel)

使用excel存储书籍的src列表和书籍的具体信息,需要使用openpyxl库进行读写excel。代码在上面write_*/read_*函数中。

效果

爬到的小说类书籍的src

爬到的书籍详细信息

后记

写这个前后大概花了有两整天吧,爬虫要做的工作还是比较细致的,需要分析HTML页面还要写正则表达式。话说,使用bs4真的是很简单,只需要copy一下selector就ok了,较正则可以大大提高效率。另外,单线程爬虫是比较蠢的。还有很多不足(诸如代码不规整,不够健壮),欢迎指正。

参考资料

python爬取豆瓣书籍_python 爬取豆瓣书籍信息相关推荐

  1. python爬取豆瓣书籍_Python 爬取豆瓣读书标签下的书籍

    这几天想爬下豆瓣读书时发现 github 上他人分享的源码都有一定年份了,豆瓣读书的页面貌似也稍微改了,于是就在前人轮子的基础上改进一下重新爬下豆瓣读书.Python 版本是 3.7. 1.爬取信息 ...

  2. python 柱状图上显示字体_Python爬取百部电影数据,我发现了这个惊人真相!

    2019年就这么匆匆过去了,就在前几天国家电影局发布了2019年中国电影市场数据,数据显示去年总票房为642.66亿元,同比增长5.4%:国产电影总票房411.75亿元,同比增长8.65%,市场占比 ...

  3. python抓取微博评论_Python爬取新浪微博评论数据,你有空了解一下?

    开发工具 Python版本:3.6.4 相关模块: argparse模块: requests模块: jieba模块: wordcloud模块: 以及一些Python自带的模块. 环境搭建 安装Pyth ...

  4. python爬取手机微信_Python爬取微信好友

    前言 今天看到一篇好玩的文章,可以实现微信的内容爬取和聊天机器人的制作,所以尝试着实现一遍,本文记录了实现过程和一些探索的内容 itchat安装 对微信的控制可以使用itchat来实现,我们找到itc ...

  5. python开源代码百度盘_python爬取百度云网盘资源-源码

    今天测试用了一下python爬取百度云网盘资源. 代码片段import urllib import urllib.request import webbrowser import re def yun ...

  6. python爬取动态网页_python爬取动态网页数据,详解

    原理:动态网页,即用js代码实现动态加载数据,就是可以根据用户的行为,自动访问服务器请求数据,重点就是:请求数据,那么怎么用python获取这个数据了? 浏览器请求数据方式:浏览器向服务器的api(例 ...

  7. python爬关键词百度指数_Python 抓取指定关键词的百度指数

    百度指数很多时候在我们做项目的时候会很有帮助,从搜索引擎的流量端给到我们一些帮助,比如:家具行业的销量跟"装修","新房","二手房"等关键 ...

  8. python 公众号文章发布_Python 抓取微信公众号文章

    版权声明:此文章转载自 Yushneng PyHub 如需转载请联系听云College团队成员阮小乙,邮箱:ruanqy#tingyun.com 微信公众号的文章链接有些是具有时效性的,过一段时间会变 ...

  9. python爬取豆瓣短评_Python爬取豆瓣指定书籍的短评

    Python爬取豆瓣指定书籍的短评 #!/usr/bin/python # coding=utf-8 import re import sys import time import random im ...

最新文章

  1. 开源软件架构总结之——Asterisk(DSL、组件、多线程)
  2. Net分布式系统之四:RabbitMQ消息队列应用
  3. 《分布式系统:概念与设计》一2.3.2 体系结构模式
  4. 2017蓝桥杯省赛---java---A---4(方格分割)
  5. pagecontrol
  6. nginx 与php版本,nginx-php不同版本问题
  7. css伪元素研究(::before/::after)
  8. 计算机3级数据库技术考哪些内容,计算机考试三级数据库技术考试大纲
  9. SpringBoot整合JWT实现前后端Token验证
  10. 服务器乌班图不显示鼠标,鼠标指针不显示怎么回事
  11. PS学习-----------图层锁定的解决办法
  12. 原理+实战|7天带你学会GAN,生活从此乐无限
  13. Java在线考试系统(含源码)
  14. 基于STM平台且满足实时控制要求的操作系统
  15. Java面试官最爱问的垃圾回收机制,mysqlssl连接
  16. 性能测试跑分软件,AE Benchmark(AE性能测试跑分工具) V1.0 免费版
  17. p6s与onvif_[海康NVR]关于NVR与ONVIF协议的问题
  18. arm linux 俄罗斯方块,ARM 俄罗斯方块 - 下载 - 搜珍网
  19. Windows Server 2008 Standard Enterprise Datacenter各个版本区别
  20. linus命令,环境变量

热门文章

  1. 翰歌世纪来成都传智播客招兵买马
  2. php获取CSV后缀文件中的内容,并把某一列的数据重写到txt文件中
  3. 比 Xshell 还好用的 SSH 客户端神器
  4. JetSonNano入门和人脸识别
  5. 不要错过,SpringBoot好玩的动态Banner
  6. JAVA抖音潜艇挑战_Android 实现抖音小游戏潜艇大挑战的思路详解
  7. 水箱自洁式消毒器定时器调整步骤
  8. 题目0013-航天器
  9. 0基础学编程树莓派和python_零基础学编程:树莓派和Python
  10. 获取当前年月日的两种方法