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 相关文章推荐
Python中的面向对象编程详解(上)
Apr 13 Python
python抓取百度首页的方法
May 19 Python
Python标准库之itertools库的使用方法
Sep 07 Python
python操作MySQL 模拟简单银行转账操作
Sep 27 Python
Python面向对象程序设计多继承和多态用法示例
Apr 08 Python
深入了解Django中间件及其方法
Jul 26 Python
Python3 翻转二叉树的实现
Sep 30 Python
python输入一个水仙花数(三位数) 输出百位十位个位实例
May 03 Python
tensorflow模型转ncnn的操作方式
May 25 Python
Python爬虫之爬取最新更新的小说网站
May 06 Python
PyQt5爬取12306车票信息程序的实现
May 14 Python
Python面向对象之成员相关知识总结
Jun 24 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
通过ODBC连接的SQL SERVER实例
2006/10/09 PHP
PHP实现网上点歌(二)
2006/10/09 PHP
使用PHP实现密保卡功能实现代码<打包下载直接运行>
2011/10/09 PHP
学习php设计模式 php实现原型模式(prototype)
2015/12/07 PHP
jQuery之网页换肤实现代码
2011/04/30 Javascript
jquery 列表双向选择器之改进版
2013/08/09 Javascript
js实现简单的网页换肤效果
2017/01/18 Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
2017/03/30 Javascript
简单实现jQuery上传图片显示预览功能
2020/06/29 jQuery
three.js实现3D视野缩放效果
2017/11/16 Javascript
Vue实现滑动拼图验证码功能
2019/09/15 Javascript
vue子组件改变父组件传递的prop值通过sync实现数据双向绑定(DEMO)
2020/02/01 Javascript
[02:29]大剑、皮鞭、女装,这届DOTA2勇士令状里都有
2020/07/17 DOTA
在Python中处理列表之reverse()方法的使用教程
2015/05/21 Python
利用python程序帮大家清理windows垃圾
2017/01/15 Python
Python之str操作方法(详解)
2017/06/19 Python
Python+selenium 获取浏览器窗口坐标、句柄的方法
2018/10/14 Python
Python Print实现在输出中插入变量的例子
2019/12/25 Python
PyQt5高级界面控件之QTableWidget的具体使用方法
2020/02/23 Python
Wiggle中国:英国骑行、跑步、游泳 & 铁三运动装备专卖网店
2016/08/02 全球购物
美国嘻哈首饰购物网站:Hip Hop Bling
2016/12/30 全球购物
英国在线发型和美容产品商店:Beauty Cutie
2019/04/27 全球购物
物业招聘计划书
2014/01/10 职场文书
银行类自荐信
2014/02/04 职场文书
节能减耗标语
2014/06/21 职场文书
日语专业求职信
2014/07/04 职场文书
营销学习心得体会
2014/09/12 职场文书
无刑事犯罪记录证明范本
2014/09/29 职场文书
群众路线对照检查剖析材料
2014/10/09 职场文书
2014年助理政工师工作总结
2014/12/19 职场文书
受资助学生感谢信
2015/01/21 职场文书
2015年人力资源工作总结
2015/04/08 职场文书
python如何做代码性能分析
2021/04/26 Python
Golang之sync.Pool使用详解
2021/05/06 Golang
Python PIL按比例裁剪图片
2022/05/11 Python
JS class语法糖的深入剖析
2022/07/07 Javascript