Python利用lxml模块爬取豆瓣读书排行榜的方法与分析


Posted in Python onApril 15, 2019

前言

上次使用了BeautifulSoup库爬取电影排行榜,爬取相对来说有点麻烦,爬取的速度也较慢。本次使用的lxml库,我个人是最喜欢的,爬取的语法很简单,爬取速度也快。

本次爬取的豆瓣书籍排行榜的首页地址是:

https://www.douban.com/doulist/1264675/?start=0&sort=time&playable=0&sub_type=

该排行榜一共有22页,且发现更改网址的 start=0 的 0 为25、50就可以跳到排行榜的第二、第三页,所以后面只需更改这个数字然后通过遍历就可以爬取整个排行榜的书籍信息。

本次爬取的内容有书名、评分、评价数、出版社、出版年份以及书籍封面图,封面图保存为图片,其他数据存为csv文件,方面后面读取分析。

本次的项目步骤:一、分析网页,确定爬取数据

二、使用lxml库爬取内容并保存

三、读取数据并选择部分内容进行分析

步骤一:

Python利用lxml模块爬取豆瓣读书排行榜的方法与分析

分析网页源代码可以看到,书籍信息在属性为的div标签中,打开发现,我们需要爬取的信息都在标签内部,通过xpath语法我们可以很简便的爬取所需内容。

Python利用lxml模块爬取豆瓣读书排行榜的方法与分析

(书籍各类信息所在标签)

所需爬取的内容在 class为post、title、rating、abstract的div标签中。

步骤二:

先定义爬取函数,爬取所需内容执行函数,并存入csv文件

具体代码如下:

import requests
from lxml import etree
import time
import csv

#信息头
headers = {
 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
}

#定义爬取函数
def douban_booksrank(url):
 res = requests.get(url, headers=headers)
 selector = etree.HTML(res.text)
 contents = selector.xpath('//div[@class="article"]/div[contains(@class,"doulist-item")]') #循环点
 for content in contents:
 try:
 title = content.xpath('div/div[2]/div[3]/a/text()')[0] #书名
 scores = content.xpath('div/div[2]/div[4]/span[2]/text()') #评分
 scores.append('9.0') #因为有一些书没有评分,导致列表为空,此处添加一个默认评分,若无评分则默认为9.0
 score = scores[0]
 comments = content.xpath('div/div[2]/div[4]/span[3]/text()')[0] #评论数量
 author = content.xpath('div/div[2]/div[5]/text()[1]')[0] #作者
 publishment = content.xpath('div/div[2]/div[5]/text()[2]')[0] #出版社
 pub_year = content.xpath('div/div[2]/div[5]/text()[3]')[0] #出版时间
 img_url = content.xpath('div/div[2]/div[2]/a/img/@src')[0] #书本图片的网址
 img = requests.get(img_url) #解析图片网址,为下面下载图片
 img_name_file = 'C:/Users/lenovo/Desktop/douban_books/{}.png'.format((title.strip())[:3]) #图片存储位置,图片名只取前3
 #写入csv
 with open('C:\\Users\lenovo\Desktop\\douban_books.csv', 'a+', newline='', encoding='utf-8')as fp: #newline 使不隔行
 writer = csv.writer(fp)
 writer.writerow((title, score, comments, author, publishment, pub_year, img_url))
 #下载图片,为防止图片名导致格式错误,加入try...except
 try:
 with open(img_name_file, 'wb')as imgf:
  imgf.write(img.content)
 except FileNotFoundError or OSError:
 pass
 time.sleep(0.5) #睡眠0.5s
 except IndexError:
 pass
#执行程序
if __name__=='__main__':
 #爬取所有书本,共22页的内容
 urls = ['https://www.douban.com/doulist/1264675/?start={}&sort=time&playable=0&sub_type='.format(str(i))for i in range(0,550,25)]
 #写csv首行
 with open('C:\\Users\lenovo\Desktop\\douban_books.csv', 'a+', newline='', encoding='utf-8')as f:
 writer = csv.writer(f)
 writer.writerow(('title', 'score', 'comment', 'author', 'publishment', 'pub_year', 'img_url'))
 #遍历所有网页,执行爬取程序
 for url in urls:
 douban_booksrank(url)

爬取结果截图如下:

Python利用lxml模块爬取豆瓣读书排行榜的方法与分析

Python利用lxml模块爬取豆瓣读书排行榜的方法与分析

步骤三:

本次使用Python常用的数据分析库pandas来提取所需内容。pandas的read_csv()函数可以读取csv文件并根据文件格式转换为Series、DataFrame或面板对象。

此处我们提取的数据转变为DataFrame(数据帧)对象,然后通过Matplotlib绘图库来进行绘图。

具体代码如下:

from matplotlib import pyplot as plt
import pandas as pd
import re

plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
plt.subplots_adjust(wsapce=0.5, hspace=0.5) #调整subplot子图间的距离

pd.set_option('display.max_rows', None) #设置使dataframe 所有行都显示

df = pd.read_csv('C:\\Users\lenovo\Desktop\\douban_books.csv') #读取csv文件,并赋为dataframe对象

comment = re.findall('\((.*?)人评价', str(df.comment), re.S) #使用正则表达式获取评论人数
#将comment的元素化为整型
new_comment = []
for i in comment:
 new_comment.append(int(i))

pub_year = re.findall(r'\d{4}', str(df.pub_year),re.S) #获取书籍出版年份
#同上
new_pubyear = []
for n in pub_year:
 new_pubyear.append(int(n))

#绘图
#1、绘制书籍评分范围的直方图
plt.subplot(2,2,1)
plt.hist(df.score, bins=16, edgecolor='black')
plt.title('豆瓣书籍排行榜评分分布', fontweight=700)
plt.xlabel('scores')
plt.ylabel('numbers')

#绘制书籍评论数量的直方分布图
plt.subplot(222)
plt.hist(new_comment, bins=16, color='green', edgecolor='yellow')
plt.title('豆瓣书籍排行榜评价分布', fontweight=700)
plt.xlabel('评价数')
plt.ylabel('书籍数量(单位/本)')

#绘制书籍出版年份分布图
plt.subplot(2,2,3)
plt.hist(new_pubyear, bins=30, color='indigo',edgecolor='blue')
plt.title('书籍出版年份分布', fontweight=700)
plt.xlabel('出版年份/year')
plt.ylabel('书籍数量/本')

#寻找关系
plt.subplot(224)
plt.bar(new_pubyear,new_comment, color='red', edgecolor='white')
plt.title('书籍出版年份与评论数量的关系', fontweight=700)
plt.xlabel('出版年份/year')
plt.ylabel('评论数')

plt.savefig('C:\\Users\lenovo\Desktop\\douban_books_analysis.png') #保存图片
plt.show()

这里需要注意的是,使用了正则表达式来提取评论数和出版年份,将其中的符号和文字等剔除。

分析结果如下:

Python利用lxml模块爬取豆瓣读书排行榜的方法与分析

本次分析的内容也较为简单,从上面的几个图形中我们也能得出一些结论。

这些高分书籍中绝大多数的评论数量都在50000以下;多数排行榜上的高分书籍都出版在2000年以后;出版年份在2000年后的书籍有更多的评论数量。

以上数据也见解的说明了在进入二十世纪后我国的图书需求量更大了,网络更发达,更多人愿意发表自己的看法。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Django 2.0版本的新特性抢先看!
Jan 05 Python
Python中的Numpy矩阵操作
Aug 12 Python
python 用下标截取字符串的实例
Dec 25 Python
python使用递归的方式建立二叉树
Jul 03 Python
使用批处理脚本自动生成并上传NuGet包(操作方法)
Nov 19 Python
解决python彩色螺旋线绘制引发的问题
Nov 23 Python
使用python 对验证码图片进行降噪处理
Dec 18 Python
利用Python计算KS的实例详解
Mar 03 Python
Python列表去重复项的N种方法(实例代码)
May 12 Python
python PyAUtoGUI库实现自动化控制鼠标键盘
Sep 09 Python
Python通过队列来实现进程间通信的示例
Oct 14 Python
如何用python 操作zookeeper
Dec 28 Python
Python常见读写文件操作实例总结【文本、json、csv、pdf等】
Apr 15 #Python
10招!看骨灰级Pythoner玩转Python的方法
Apr 15 #Python
Python后台开发Django会话控制的实现
Apr 15 #Python
浅析Python 实现一个自动化翻译和替换的工具
Apr 14 #Python
提升Python程序性能的7个习惯
Apr 14 #Python
Python根据当前日期取去年同星期日期
Apr 14 #Python
Python实现的微信支付方式总结【三种方式】
Apr 13 #Python
You might like
php file_get_contents函数轻松采集html数据
2010/04/22 PHP
php中动态变量用法实例
2015/06/10 PHP
Yii2 输出xml格式数据的方法
2016/05/03 PHP
php的命名空间与自动加载实现方法
2019/08/25 PHP
yii2.0框架数据库操作简单示例【添加,修改,删除,查询,打印等】
2020/04/13 PHP
jquery imgareaselect 使用利用js与程序结合实现图片剪切
2009/07/30 Javascript
jQuery瀑布流插件Wookmark使用实例
2014/04/02 Javascript
Javascript中使用A标签获取当前目录的绝对路径方法
2015/03/02 Javascript
浅谈类似于(function(){}).call()的js语句
2015/03/30 Javascript
js实现选中页面文字将其分享到新浪微博
2015/11/05 Javascript
javascript结合Flexbox简单实现滑动拼图游戏
2016/02/18 Javascript
HTML页面,测试JS对C函数的调用简单实例
2016/08/09 Javascript
AngularJs  E2E Testing 详解
2016/09/02 Javascript
详解keep-alive + vuex 让缓存的页面灵活起来
2019/04/19 Javascript
对于防止按钮重复点击的尝试详解
2019/04/22 Javascript
python实现发送和获取手机短信验证码
2016/01/15 Python
python采用django框架实现支付宝即时到帐接口
2016/05/17 Python
Python+django实现简单的文件上传
2016/08/17 Python
Python实现求一个集合所有子集的示例
2018/05/04 Python
python中强大的format函数实例详解
2018/12/05 Python
Python高级特性 切片 迭代解析
2019/08/23 Python
关于jupyter打开之后不能直接跳转到浏览器的解决方式
2020/04/13 Python
HTML5实践-图片设置成灰度图
2012/11/12 HTML / CSS
美国探亲签证邀请信
2014/02/05 职场文书
自荐信的基本格式
2014/02/22 职场文书
客服部班长工作责任制
2014/02/25 职场文书
社区关爱留守儿童活动方案
2014/08/22 职场文书
中队活动总结
2014/08/27 职场文书
解除劳动合同协议书
2014/09/17 职场文书
销售员未完成销售业绩的检讨书
2014/10/12 职场文书
班主任寄语2015
2015/02/26 职场文书
名人传读书笔记
2015/06/26 职场文书
《百分数的认识》教学反思
2016/02/19 职场文书
Matplotlib绘制混淆矩阵的实现
2021/05/27 Python
使用react-virtualized实现图片动态高度长列表的问题
2021/05/28 Javascript
图文详解matlab原始处理图像几何变换
2021/07/09 Python