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 相关文章推荐
pandas求两个表格不相交的集合方法
Dec 08 Python
python画图的函数用法以及技巧
Jun 28 Python
Python3显示当前时间、计算时间差及时间加减法示例代码
Sep 07 Python
新年福利来一波之Python轻松集齐五福(demo)
Jan 20 Python
OpenCV Python实现拼图小游戏
Mar 23 Python
Python pip install如何修改默认下载路径
Apr 29 Python
Python函数参数分类原理详解
May 28 Python
keras在构建LSTM模型时对变长序列的处理操作
Jun 29 Python
python中加背景音乐如何操作
Jul 19 Python
Python生成九宫格图片的示例代码
Apr 14 Python
Python关于OS文件目录处理的实例分享
May 23 Python
pytorch Dropout过拟合的操作
May 27 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
PHPMYADMIN 简明安装教程 推荐
2010/03/07 PHP
用穿越火线快速入门php面向对象
2012/02/22 PHP
简单的php中文转拼音的实现代码
2014/02/11 PHP
Laravel 5框架学习之路由、控制器和视图简介
2015/04/07 PHP
微信开发之网页授权获取用户信息(二)
2016/01/08 PHP
Zend Framework路由器用法实例详解
2016/12/11 PHP
用roll.js实现的图片自动滚动+鼠标触动的特效
2007/03/18 Javascript
网页上的Javascript编辑器和代码格式化
2010/04/25 Javascript
Asp.net下利用Jquery Ajax实现用户注册检测(验证用户名是否存)
2010/09/12 Javascript
File, FileReader 和 Ajax 文件上传实例分析(php)
2011/04/27 Javascript
用Javascript来生成ftp脚本的小例子
2013/07/03 Javascript
使用CSS和jQuery模拟select并附提交后取得数据的代码
2013/10/18 Javascript
js实现的点击div区域外隐藏div区域
2014/06/30 Javascript
Nodejs实现多人同时在线移动鼠标的小游戏分享
2014/12/06 NodeJs
JavaScript中的console.dir()函数介绍
2014/12/29 Javascript
利用jQuery和CSS将背景图片拉伸
2015/10/16 Javascript
JavaScript中rem布局在react中的应用
2015/12/09 Javascript
JavaScript中数组去除重复的三种方法
2016/04/22 Javascript
javascript三种代码注释方法
2016/06/02 Javascript
Angular工具方法学习
2016/12/26 Javascript
前端防止用户重复提交js实现代码示例
2018/09/07 Javascript
node全局变量__dirname与__filename的区别
2019/01/14 Javascript
javascript实现小型区块链功能
2019/04/03 Javascript
Python运用于数据分析的简单教程
2015/03/27 Python
用PyInstaller把Python代码打包成单个独立的exe可执行文件
2018/05/26 Python
使用PM2+nginx部署python项目的方法示例
2018/11/07 Python
python各类经纬度转换的实例代码
2019/08/08 Python
Python实现微信翻译机器人的方法
2019/08/13 Python
PyTorch实现ResNet50、ResNet101和ResNet152示例
2020/01/14 Python
Python extract及contains方法代码实例
2020/09/11 Python
本科生职业生涯规划书范文
2014/01/21 职场文书
新学期开学演讲稿
2014/05/24 职场文书
乡镇群众路线整改落实情况汇报
2014/10/28 职场文书
师德标兵先进事迹材料
2014/12/19 职场文书
锅炉工岗位职责
2015/02/13 职场文书
python百行代码实现汉服圈图片爬取
2021/11/23 Python