当当网Top500书籍信息爬取与分析

news2025/5/10 22:27:18

爬取当当网的Top500书籍信息,并对书籍的评价数量进行排序,然后绘制前十名的条形图,然后对各个出版社出版的书籍数量进行排序,绘制百分比的饼图

# 导入所需的模块
import re  # 正则表达式模块,用于提取文本中的特定模式
from time import sleep  # 用于在循环中添加延迟,避免请求过于频繁
import csv  # 用于读写CSV文件
import requests  # 用于发送HTTP请求,获取网页内容
import pandas as pd  # 用于数据处理和分析
import matplotlib.pyplot as plt  # 用于绘制图表
import numpy as np  # 用于数值计算

# 设置请求头,模拟浏览器访问,避免被网站识别为爬虫
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
}

# 定义函数,从网页获取特定页面的内容,并以列表形式返回
def getInfo(page):
    page = str(page)  # 将页码转换为字符串
    # 构造目标网页的URL,这里使用了一个无效的网页地址,需要替换成有效的当当网图书排行榜页面URL
    url = '<url id="d0f0ofd96bk4h4b9797g" type="url" status="parsed" title="对不起,您要访问的页面暂时没有找到。" wc="658">http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-</url> ' + page
    # 发送GET请求,获取网页内容
    response = requests.get(url=url, headers=headers).text
    # 使用正则表达式提取网页中的<li>标签内容
    ex = '(?<=<li>\\s)[\\w\\W]*?(?=</li>)'
    p = re.findall(ex, response)  # 在网页内容中查找所有匹配的模式
    del p[0:3]  # 删除前三个无用的元素(假设前三个元素不是书籍信息)
    return p  # 返回提取到的书籍信息列表

# 定义函数,从字符串中提取书籍的序号
def getIndex(str):
    ex = 'list_num.*?>(.*?)<'  # 匹配序号的正则表达式
    p = re.findall(ex, str)
    return p[0]  # 返回提取到的序号

# 定义函数,从字符串中提取书籍的名称
def getName(str):
    ex = 'title="(.*?)"\\/'  # 匹配书名的正则表达式
    p = re.findall(ex, str)
    return p[0]  # 返回提取到的书名

# 定义函数,从字符串中提取书籍的评论数量
def getCommentCount(str):
    ex = '_blank">([\d]+.*?)<'  # 匹配评论数量的正则表达式
    p = re.findall(ex, str)
    return p[0]  # 返回提取到的评论数量

# 定义函数,从字符串中提取书籍的作者
def getWriter(str):
    ex = 'title="(.*?)"'  # 匹配作者的正则表达式
    p = re.findall(ex, str)
    try:
        return p[2]  # 尝试返回第三个匹配结果(假设作者信息是第三个匹配项)
    except:
        return "暂未找到"  # 如果匹配失败,返回默认值

# 定义函数,从字符串中提取书籍的出版时间
def getTime(str):
    ex = '<span>(.*?)<'  # 匹配出版时间的正则表达式
    p = re.findall(ex, str)
    return p[0]  # 返回提取到的出版时间

# 定义函数,从字符串中提取书籍的出版社
def getPub(str):
    ex = 'key=(.*?)"'  # 匹配出版社的正则表达式
    p = re.findall(ex, str)
    return p[-1]  # 返回最后一个匹配结果(假设出版社信息是最后一个匹配项)

# 定义函数,从字符串中提取书籍的原价
def getPriceFir(str):
    ex = 'price_r">.*?;(.*)<'  # 匹配原价的正则表达式
    p = re.findall(ex, str)
    return p[0]  # 返回提取到的原价

# 定义函数,从字符串中提取书籍的促销价格
def getPriceNow(str):
    ex = 'price_n">.*?;(.*)<'  # 匹配促销价的正则表达式
    p = re.findall(ex, str)
    return p[0]  # 返回提取到的促销价

# 定义主函数,用于爬取多页数据并保存到CSV文件
def main():
    for page in range(1, 26):  # 循环遍历1到25页
        book_list = getInfo(page)  # 获取当前页的书籍列表
        with open('book.csv', 'a', encoding='UTF-8', newline='') as f:  # 打开或创建CSV文件,追加模式
            writer = csv.writer(f)  # 创建CSV写入对象
            # 如果文件是新建的(指针位置为0),则写入表头
            if f.tell() == 0:
                writer.writerow(["序号", "书名", "作者", "出版时间", "出版社", "原价", "促销价","评价量"])
            for info in book_list:  # 遍历每本书的信息
                index = getIndex(info)  # 提取序号
                name = getName(info)  # 提取书名
                priceFir = getPriceFir(info)  # 提取原价
                priceNow = getPriceNow(info)  # 提取促销价
                try:
                    # 提取评论数量,并移除"条评论"字样
                    commentCount = getCommentCount(info).replace("条评论", "")
                except Exception as e:
                    commentCount = 0  # 如果提取失败,设置默认值为0
                writer_name = getWriter(info)  # 提取作者
                pub_time = getTime(info)  # 提取出版时间
                pub = getPub(info)  # 提取出版社
                # 将提取到的信息写入CSV文件
                writer.writerow([index, name, writer_name, pub_time, pub, priceFir, priceNow, commentCount])
        sleep(0.5)  # 每次请求后暂停0.5秒,避免请求过于频繁

# 执行主函数,开始爬取数据
main()

# 读取保存的CSV文件,准备数据分析和可视化
df = pd.read_csv('book.csv', encoding='utf-8')

# 按评价数量降序排序,并取前十名书籍
top_books = df.sort_values(by='评价量', ascending=False).head(10)

# 处理书名,使其每20个字符换一行,便于在图表中显示
top_books['书名'] = top_books['书名'].apply(lambda x: '\n'.join([x[i:i+20] for i in range(0, len(x), 20)]))

# 设置字体,确保正确显示中文和负号
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

# 创建一个新的图形,设置大小为12x8英寸
plt.figure(figsize=(12, 8))

# 绘制评价数量前十名的书籍的水平条形图
bars = plt.barh(top_books['书名'], top_books['评价量'], color='skyblue')

# 为每个条形添加数据标签
for bar in bars:
    width = bar.get_width()
    plt.text(width - 210000, bar.get_y() + bar.get_height()/2, f'{int(width):,}', va='center')

# 再次绘制条形图以确保标签正确显示
plt.barh(top_books['书名'], top_books['评价量'], color='skyblue')

# 添加坐标轴标签和图表标题
plt.xlabel('评价数量')
plt.title('评价数量前十名的书籍')

# 反转Y轴,使评价最多的书籍显示在顶部
plt.gca().invert_yaxis()

# 调整布局,确保所有元素都能正确显示
plt.tight_layout()

# 显示图表
plt.show()

# 统计各出版社出版的书籍数量
publisher_counts = df['出版社'].value_counts()

# 将数量小于等于2的出版社和空白出版社归类为“其他”
threshold = 3
other = publisher_counts[publisher_counts <= threshold].sum() + publisher_counts.get('', 0)
publisher_counts = publisher_counts[publisher_counts > threshold]
publisher_counts = publisher_counts.drop('', errors='ignore')  # 删除空白出版社
publisher_counts['其他'] = other  # 添加“其他”类别

# 绘制出版社百分比饼图
plt.figure(figsize=(10, 10))
patches, texts, autotexts = plt.pie(publisher_counts, autopct='%1.1f%%', startangle=140)

# 添加图例
plt.legend(patches, publisher_counts.index, loc='lower center', bbox_to_anchor=(0.5, -0.2), ncol=5)

# 添加图表标题
plt.title('各出版社出版书籍数量百分比')

# 调整布局并显示图表
plt.tight_layout()
plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2372667.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

修复笔记:获取 torch._dynamo 的详细日志信息

一、问题描述 在运行项目时&#xff0c;遇到与 torch._dynamo 相关的报错&#xff0c;并且希望获取更详细的日志信息以便于进一步诊断问题。 二、相关环境变量设置 通过设置环境变量&#xff0c;可以获得更详细的日志信息&#xff1a; set TORCH_LOGSdynamo set TORCHDYNAM…

Windows平台下的Qt发布版程序打包成exe可执行文件(带图标)|Qt|C++

首先先找一个可执行文件的图标 可以去阿里的矢量图库里找 iconfont-阿里巴巴矢量图标库 找到想要的图标下载下来 此时的图标是png格式的&#xff0c;我们要转到icon格式的文件 要使用到一个工具Drop Icons_2.1.1.rar - 蓝奏云 生成icon文件后把icon文件放到你项目的根目录下…

CSS--图片链接垂直居中展示的方法

原文网址&#xff1a;CSS--图片链接垂直居中展示的方法-CSDN博客 简介 本文介绍CSS图片链接垂直居中展示的方法。 图片链接 问题复现 源码 <html xml:lang"cn" lang"cn"><head><meta http-equiv"Content-Type" content&quo…

TRAE 配置blender MCP AI自动3D建模

BlenderMCP - Blender模型上下文协议集成 BlenderMCP通过模型上下文协议(MCP)将Blender连接到Claude AI&#xff0c;允许Claude直接与Blender交互并控制Blender。这种集成实现了即时辅助的3D建模、场景创建和操纵。 1.第一步下载 MCP插件(addon.py):Blender插件&#xff0c;在…

VUE2课程计划表练习

主要练习数据变量对象 以下是修正后的完整代码&#xff1a; //javascript export default {data() {return {list: [{ id: 1, subject: Vue.js 前端实战开发, content: 学习指令&#xff0c;例如 v-if、v-for、v-model 等, place: 自习室, status: false }// 可以在这里添加更…

2025年软件工程与数据挖掘国际会议(SEDM 2025)

2025 International Conference on Software Engineering and Data Mining 一、大会信息 会议简称&#xff1a;SEDM 2025 大会地点&#xff1a;中国太原 收录检索&#xff1a;提交Ei Compendex,CPCI,CNKI,Google Scholar等 二、会议简介 2025年软件开发与数据挖掘国际会议于…

.NET高频技术点(持续更新中)

1. .NET 框架概述 .NET 框架的发展历程.NET Core 与 .NET Framework 的区别.NET 5 及后续版本的统一平台 2. C# 语言特性 异步编程&#xff08;async/await&#xff09;LINQ&#xff08;Language Integrated Query&#xff09;泛型与集合委托与事件属性与索引器 3. ASP.NET…

pandas中的数据聚合函数:`pivot_table` 和 `groupby`有啥不同?

pivot_table 和 groupby 是 pandas 中两种常用的数据聚合方法&#xff0c;它们都能实现数据分组和汇总&#xff0c;但在使用方式和输出结构上有显著区别。 0. 基本介绍 groupby分组聚合 groupby 是 Pandas 库中的一个功能强大的方法&#xff0c;用于根据一个或多个列对数据进…

对golang中CSP的理解

概念&#xff1a; CSP模型&#xff0c;即通信顺序进程模型&#xff0c;是由英国计算机科学家C.A.R. Hoare于1978年提出的。该模型强调进程之间通过通道&#xff08;channel&#xff09;进行通信&#xff0c;并通过消息传递来协调并发执行的进程。CSP模型的核心思想是“不要通过…

【LunarVim】CMake LSP配置

在 LunarVim 中为 CMakeLists.txt 文件启用代码提示&#xff08;如补全和语义高亮&#xff09;&#xff0c;需要安装支持 CMake 的 LSP&#xff08;语言服务器&#xff09;和适当的插件。以下是完整配置指南&#xff1a; 1、配置流程 1.1 安装cmake-language-server 通过 Ma…

Mkdocs页面如何嵌入PDF

嵌入PDF 嵌入PDF代码 &#xff0c;注意PDF的相对地址 <iframe src"../个人简历.pdf (相对地址)" width"100%" height"800px" style"border: 1px solid #ccc; overflow: auto;"></iframe>我的完整代码&#xff1a; <d…

融合静态图与动态智能:重构下一代智能系统架构

引言&#xff1a;智能系统的分裂 当前的大模型系统架构正处于两个极端之间&#xff1a; 动态智能体系统&#xff1a;依赖语言模型动态决策、自由组合任务&#xff0c;智能灵活但稳定性差&#xff1b; 静态流程图系统&#xff1a;具备强工程能力&#xff0c;可控可靠&#xf…

WORD压缩两个免费方法

日常办公和学习中&#xff0c;Word文档常常因为包含大量图片、图表或复杂格式而导致文件体积过大&#xff0c;带来诸多不便&#xff0c;比如 邮件发送受限&#xff1a;许多邮箱附件限制在10-25MB&#xff0c;大文件无法直接发送 存储空间占用&#xff1a;大量文档占用硬盘或云…

skywalking服务安装与启动

skywalking服务安装并启动 1、介绍2、下载apache-skywalking-apm3、解压缩文件4、创建数据库及用户5、修改配置文件6、下载 MySQL JDBC 驱动7、启动 OAP Serve,需要jkd11,需指定jkd版本,可以修改文件oapService.sh8、启动 Web UI,需要jkd11,需指定jkd版本,可以修改文件oapServi…

Qt 中信号与槽(signal-slot)机制支持 多种连接方式(ConnectionType)

Qt 中信号与槽&#xff08;signal-slot&#xff09;机制支持 多种连接方式&#xff08;ConnectionType&#xff09; Qt 中信号与槽&#xff08;signal-slot&#xff09;机制支持 多种连接方式&#xff08;ConnectionType&#xff09;&#xff0c;用于控制信号发出后如何调用槽…

Midjourney-V7:支持参考图片头像或背景生成新保真图

Midjourney-V7重磅升级Omni Reference&#xff1a;全能图像参考神器&#xff01;再也不用担心生成图片货不对版了&#xff01; 就在上周&#xff0c;Midjourney发版它最新的V7版本&#xff1a;Omini Reference&#xff0c;提供了全方位图像参考功能&#xff0c;它可以参考你提…

耀圣-气动带刮刀硬密封法兰球阀:攻克颗粒高粘度介质的自清洁 “利器”

气动带刮刀硬密封法兰球阀&#xff1a;攻克颗粒高粘度介质的自清洁 “利器” 在化工、矿业、食品加工等行业中&#xff0c;带颗粒高粘度介质、料浆及高腐蚀性介质的输送与控制一直是行业难题。普通阀门极易因介质附着、颗粒堆积导致卡阻失效&#xff0c;密封面磨损加剧&#x…

Google云计算原理和应用之分布式锁服务Chubby

Chubby是Google设计的提供粗粒度锁服务的一个文件系统,它基于松耦合分布式系统,解决了分布的一致性问题。通过使用Chubby的锁服务,用户可以确保数据操作过程中的一致性。不过值得注意的是,这种锁只是一种建议性的锁(Advisory Lock)而不是强制性的锁,这种选择系统具有更大…

SM2Utils NoSuchMethodError: org.bouncycastle.math.ec.ECFieldElement$Fp.<init

1&#xff0c;报错图示 2&#xff0c;报错原因&#xff1a; NoSuchMethodError 表示运行时找不到某个方法&#xff0c;通常是编译时依赖的库版本与运行时使用的库版本不一致。 错误中的 ECFieldElement$Fp. 构造函数参数为 (BigInteger, BigInteger)&#xff0c;说明代码期望使…

《100天精通Python——基础篇 2025 第16天:异常处理与调试机制详解》

目录 一、认识异常1.1 为什么要使用异常处理机制?1.2 语法错误1.3 异常错误1.4 如何解读错误信息 二、异常处理2.1 异常的捕获2.2 Python内置异常2.3 捕获多个异常2.4 raise语句与as子句2.5 使用traceback查看异常2.6 try…except…else语句2.7 try…except…finally语句--捕获…