基于 Python 的豆瓣图书数据采集、预处理与应用实践
|
个 人 总 结 |
本项目旨在通过Python编程语言,结合网络爬虫技术和数据解析工具,实现对豆瓣图书网站上的分类信息及书籍详情的自动化抓取,并将获取的数据以结构化的方式保存下来。以下是详细的步骤说明: 1. 确定数据来源 图书大类:首先明确豆瓣图书网提供的六大类别——文学、流行、文化、生活、经管和科技。这些大类构成了我们后续抓取的基础框架。小类信息:基于上述六大类别,进一步访问每个大类下的标签页面,从中抽取更为细化的小类信息。具体来说,包括但不限于大类编号、小类编号、小类名称、该类别下图书的数量以及指向相应小类别的链接。图书详细信息:深入到每本书籍的具体页面,收集诸如书名、出版详情(如作者、出版社等)、封面图片链接等更详尽的内容。这部分数据来源于各小类列表页中的单个条目详情。 2. 设置请求头 为了模拟真实的浏览器行为,避免触发目标站点的反爬虫机制,我们在发起HTTP请求时设置了自定义的`UserAgent`字段。这使得服务器端认为接收到的是来自普通用户的正常访问请求,而非自动化脚本或恶意程序。 3. 数据解析 正则表达式:作为一种强大的文本模式匹配工具,正则表达式允许我们从非结构化的HTML源码中精确地筛选出所需元素。例如,可以构建特定模式来定位并提取网页内的URL地址或者按照固定格式的时间戳记录。 lxml库:利用lxml库提供的高效DOM解析能力,我们可以轻松地将HTML文档转换成易于遍历的树状结构。借助XPath查询语言,能够快速定位到感兴趣的节点,并从中读取属性值或子元素内容。此外,lxml还支持对原始文档进行修改,满足某些场景下的动态调整需求。 BeautifulSoup库:作为另一个流行的HTML/XML解析器,BeautifulSoup以其简洁易用而著称。它不仅提供了丰富的API用于查找、过滤和操作文档树中的各个部分,而且内置了多种解析引擎供选择,确保兼容性和性能之间的平衡。 在本次实验中,考虑到效率与灵活性的要求,选择了正则表达式搭配lxml来进行主要的数据挖掘工作。 4. 获取图书大类信息 构建初始URL,指向豆瓣图书的分类概览页面。 使用`requests.get()`函数发出GET请求,接收返回的HTML文本。应用`etree.HTML()`方法将字符串形式的HTML转换为可供后续处理的对象。最后,采用Pandas库中的`DataFrame.to_csv()`功能,把整理好的大类信息导出至本地CSV文件。 5. 获取图书小类信息 创建一个空列表`categoryLst`用来累积所有小类别的元数据。运用`enumerate()`迭代`categoryTitle`(即大类名称数组),同时调用XPath表达式分别获取每个大类下的子项。通过`zip()`组合小类名称、图书数目及对应的URL,再赋予唯一标识符(即小类编号),最终形成完整的记录加入到`categoryLst`中。同样地,使用`DataFrame.to_csv()`保存包含小类信息的数据集,确保文件编码为UTF8,并添加索引列以便于查阅。 6. 获取图书详细信息 依据之前生成的小类CSV文档,逐条加载小类链接,针对每个类别执行分页抓取策略,确保覆盖全部相关书籍。 对于每本书而言,重点提取其标题、出版商、评分星级、评论数量及封面图链接等关键要素。将收集到的信息组织成列表结构返回给上层逻辑,准备下一步骤的处理或持久化操作。在整个数据采集流程中,不可避免地会遇到各种意外状况,比如网络连接中断、服务器拒绝服务或是本地I/O操作失败等。为此,我们在代码层面加入了全面的异常捕捉机制,当检测到任何异常事件时,系统将立即停止当前任务,输出详细的错误描述,并根据实际情况采取适当的补救措施。这样做不仅提高了程序的整体稳定性和可靠性,也为调试和维护带来了极大的便利。 综上所述,遵循以上设计思路,我们能够有条不紊地完成从确定数据源到最终结果输出的全过程。通过对豆瓣图书网站的大类、小类及其内部书籍信息的有效抓取,不仅积累了大量有价值的数据资源,同时也验证了所选技术方案的可行性和优越性。未来,随着项目的不断演进和技术手段的日臻完善,相信可以在更多领域内发挥重要作用。 (二)代码和运行截图:(注释或者说明) 1. 设置请求头模拟浏览器的用户代理信息,让服务器认为请求是来自正常的浏览器访问,避免在发送请求时被反爬虫机制而导致的请求被拒绝情况,如图1.1所示。 图1.1 设置请求头 2.获取大类信息,定位豆瓣图书标签分类页面网址,获取网页内容并以文本形式返回,提取解析文本后,通过xpath表达式获取大类名称,将信息存入数据框中保存csv文件,如图1.2,图1.3,图1.4,图1.5所示。
图1.2 大类信息
3.获取小类信息,初始化一个空列表,通过遍历大类名称循环提取大类下的小类名称,小类图书数量,小类网址,将提取的小类信息同大类信息一同并入空列表中,最后将空列表信息保存为csv文件,如图1.3,图1.4。
图1.4 获取小类信息
图1.5 小类信息 4.获取图书详细信息,读取图书小类表遍历小类信息,设置自动翻页提取网页信息,将文件写入图书详细信息表,图1.6,图1.7。
图1.6 获取图书详细信息
图1.7 图书详细信息 (三)总结: 1. 遇到的问题 在执行网页信息提取的过程中,遇到了几类主要挑战: 网络通信障碍:包括但不限于网络超时、连接被拒绝以及DNS解析失败等问题,这些问题直接影响了我们获取目标网页内容的能力。 数据库操作难题:当涉及到大规模的数据存储时,可能会遭遇数据库连接不稳定、数据插入失败或存储空间不足等困境。这些问题不仅影响了数据的完整性,还可能程序运行中断。 反爬虫机制应对:为了防止恶意爬虫行为,许多网站部署了严格的防护措施,如限制IP访问频率、检测UserAgent(UA)、引入验证码验证,甚至是采用JavaScript动态加载内容的方式,这些都增加了抓取工作的难度。 2. 解决方法 针对上述问题,有效的解决方案: 规避反爬虫限制:为了避免触发网站的反爬虫机制,我们在编写爬虫脚本时特别注意控制请求频率,确保不会对目标站点造成过大的负载压力。与此同时,借助`fake_useragent`库随机生成多样化的UA字符串,使得我们的爬虫请求更加贴近真实用户的浏览习惯。面对验证码这一障碍,可以考虑集成第三方OCR服务进行自动识别,或者提供人工辅助输入选项。最后,对于那些依赖JavaScript渲染的内容,我们选择了像Selenium这样的工具来模拟浏览器行为,从而顺利绕过了此类技术壁垒。 3. 技术成长与心得 在整个项目实施期间,我深刻体会到掌握Python编程语言及其相关库的重要性。从最初接触Python的基础语法开始,经过不断的练习与实践,我已经能够熟练运用`requests`库发送HTTP请求,并且掌握了`lxml`和`BeautifulSoup`这两个强大的HTML/XML解析库,特别是它们各自独特的选择器语法——XPath和CSS Selectors,极大地提高了我的数据抽取效率。特别是在处理JavaScript驱动的动态页面时,学习`Selenium`库及其配套的WebDriver接口成为突破瓶颈的关键一步。此外,我还探索了如何将抓取的数据有效组织起来,无论是保存为CSV文件还是导入关系型数据库MySQL或是非关系型数据库MongoDB,都能够根据实际需求灵活选择最适合的数据持久化方案。 随着经验的积累,我逐渐从简单的单页信息采集过渡到了更为复杂的多页甚至跨站信息聚合任务,如校园讲座信息的综合整理。在这个过程中,我学会了如何设计合理的代码结构以避免重复抓取相同的数据,并且实现了高效的数据清洗流程。参与更大规模的项目则让我直面高并发访问、海量数据处理以及复杂反爬虫策略带来的挑战。通过引入分布式爬虫框架`Scrapy`,结合代理IP池管理和随机UA切换等高级技巧,最终成功地实现了稳定而高效的自动化数据收集过程。 项目2:数据预处理 (一)步骤: 1.读取csv文件进行初步处理 拆分“图书详细信息表.csv”的“出版信息”字段,分为 作者 出版社 出版年份, 价格(提取数字和小数点)存入DataFrame中。 2. 删除和合并 将“出版信息”字段删除,让后将拆分后的DataFrame与删除后的结果 进行合并,并写入“图书详细信息表2.csv” 3. 多文件合并,进行信息提取 获取图书的大类名称,小类名称,图书名称,作者姓名,得分和评论人数。分类统计。统计每个大类的图书的平均评价人数,平均分数,每个大类的得分的 总分和评价总人数。 4.绘制柱状图统计结果。 (二)代码和运行截图: 1.读取前面部分提取的图书详细信息表,拆分图书详细表,将出版信息中按照“/”分隔符进行分割,将分割后的部分存储在列表中,通过正则表达式将列表中的数字、文字信息匹配提取出来,并分别赋值于新列表中,用于构建新的DataFrame,如图2.1。
图2.1 拆分信息 2.合并两个数据框架 使用merge方法按照索引(left_index=True和right_index=True表示以两个DataFrame的索引进行合并)将两框架进行合并,将新提取出来的关于作者、出版社等信息与原始的图书详细信息整合到一起,合并后的结果存储在df中。调用drop方法删除df中名为出版信息的列,因为相关信息已经经过处理并拆分到新的列中了,所以可以删除原来的这一列,避免数据冗余,最后保存数据,如图2.2。
图2.2 合并删除重复
3.合并大类小类 实现读取多个与图书相关的 CSV 文件,提取并整合其中的关键信息(如图书大类、小类、详情信息等),通过多次合并操作将这些信息汇总到一个数据框中,并对数据框进行了列顺序整理等操作,如图2.4。
图2.4 合并大类小类 4.数据可视化 实现了读取图书相关的 CSV 文件数据,对数据进行分组、聚合、合并等处理操作,然后通过matplotlib库绘制出包含四个子图的可视化图形,分别展示不同图书大类在评论总得分、总人数、平均得分、平均人数方面的情况,帮助用户更直观地分析和理解图书数据的相关统计特征,如图2.5,图2.6。
图2.5 数据可视化
图2.6 绘制图像 (三)总结: 数据预处理中的挑战与解决方案 1. 遇到的问题 在数据预处理阶段,我们通常会遇到以下几类问题: 缺失值:数据集中某些字段或记录存在缺失值。这可能是由于数据收集过程中的疏忽、设备故障或其他原因造成的。 异常值与噪声:数据中可能存在错误、异常或偏离正常范围的值。这些异常值可能来源于数据录入错误、传感器故障或极端情况的发生。 图表选择不当:所选的图表类型不适合数据的特点和分析目的,导致难以准确传达信息或误导读者。 2. 解决方法 针对上述问题,我们可以采取如下措施来改善数据质量和可视化效果: 删除缺失值:当缺失值的比例较小时(例如小于5%),可以直接删除包含缺失值的行或列。然而,这种方法可能导致数据量减少,信息丢失,因此需谨慎使用。 填充缺失值:根据数据的特点和分布,选择合适的填充方法。对于数值型变量,可以使用均值、中位数或众数进行填充;对于分类变量,则可以选择最频繁出现的类别作为替代。此外,还可以基于已有数据建立预测模型来填补缺失值,如K近邻算法、线性回归等。 数据平滑:采用移动平均、加权平均等方法对数据进行平滑处理,以减少噪声的影响。特别是对于时间序列数据,滑动窗口平均法是一种有效的平滑技术。 异常值检测与处理:通过设定阈值、应用统计方法(如3σ原则)或利用聚类、分类等算法识别异常值。一旦确定了异常值,可以根据具体情况决定是删除它们、修正为合理值还是将其单独作为特殊情况进行分析。 在选择图表时,应充分考虑数据的性质以及想要表达的信息。例如,对于连续型变量,折线图或散点图可能是更好的选择;而对于分类变量,条形图或饼图则更为合适。确保图表能够清晰地展示数据趋势,并有助于理解数据背后的含义。 3. 总结 数据预处理是数据分析、挖掘和机器学习项目中不可或缺的关键步骤。它涵盖了从原始数据的清理、转换、整合到优化等多个方面,旨在提高数据质量,为后续深入分析和模型构建奠定坚实基础。 数据清理:重点在于处理缺失值。根据缺失的程度和特性,可以选择删除含有缺失值的记录,尽管这种方法简单但可能导致信息损失;或者采用更保守的方法,如用均值、中位数填充数值型变量,用众数填充分类变量,甚至使用预测模型智能填补缺失值。同时,重复值的处理也非常重要,通过数据库或编程工具提供的去重功能,依据关键列识别并删除重复记录,同时加强数据录入审核,预防重复数据的产生。对于噪声数据,可以采用数据平滑技术,如移动平均或加权平均,使数据波动趋于平稳,也可以通过统计规则和异常值识别算法定位并处理异常值,确保数据准确性。 数据转换:常见的操作包括类型转换,如将字符串型日期转换为日期型,以便于进行日期相关的计算。数据标准化和归一化也是至关重要的步骤,它们通过特定算法将不同量级和分布的数据调整到相似尺度,保证数据在模型训练中的公平性和效率,避免因数据量级差异导致模型偏差。对于分类数据,通过独热编码、标签编码等方法将文本类别信息转换为数值形式,使得模型能够更好地处理。 数据整合:涉及从多个数据源汇聚数据,在格式、编码、语义等方面进行统一,通过清洗和转换消除差异,最终合并成一个完整的数据集。这一过程需要解决诸如实体识别、冗余去除等问题,确保集成后的数据集既具有一致性又保持了原始信息的完整性。 特征工程:这是数据预处理的一个高级阶段,特征选择根据相关性和重要性筛选出对目标变量最有价值的特征,减少数据冗余;特征降维则通过主成分分析、线性判别分析等方法将高维数据投影到低维空间,保留核心信息的同时降低计算成本和模型复杂度。 综上所述,数据预处理不仅是一系列具体的操作,更是一个需要结合数据特性、项目目标及后续需求精心设计的过程。通过对数据进行全面而细致的预处理,我们可以显著提升数据的质量,进而支持整个数据分析和应用项目的顺利开展。 项目3:GUI 编程 简易计算器与调查问卷的设计与实现 一、简易计算器的开发步骤 1. 确定整体结构与初始化 2. 构造函数接收主窗口对象 3. 构建交互按键 4. 编写交互程序 通过 Grid 布局安排数字和运算符按钮,以及结果显示区域,确保了界面的整洁和有序。学习了如何利用 Tkinter 的 Label、Button 和 Entry 组件,并掌握了通过调整属性来定制界面样式的方法。为界面上的每个按钮分配回调函数,以响应用户的点击事件,从而掌握了事件处理机制。此外,使用 eval() 函数简化了算术表达式的处理过程,并增强了程序的健壮性。 二、调查问卷的设计与实现 1. 数据准备与初始化 2. 创建滚动框架及布局 3. 生成题目及选项组件 4. 创建提交按钮及关联功能 5. 计算得分功能 (二)代码和运行截图:(注释或者说明) 1. 简易计算器 (1).创建显示屏 首先,创建一个名为`display_frame`的框架(`Frame`),这个框架将作为显示屏的容器。使用`grid`布局管理器将`display_frame`放置在主窗口的第一行第一列,并设置它跨越4列(`columnspan=4`),这样它就会占据整个窗口的顶部一行。设置`display_frame`在四个方向(上、下、左、右)都能自适应拉伸,以适应窗口大小的变化。在`display_frame`内部创建一个`Entry`输入框,这个输入框将作为显示屏,用于显示用户输入的表达式和计算结果。设置`Entry`输入框的显示属性,如字体大小和边框宽度等,以提高可读性和美观度。使用`grid`布局管理器让`Entry`输入框占满整个`display_frame`空间,确保它也能自适应窗口大小的变化。配置`display_frame`内组件的内外边距(`padx`和`pady`),以及设置行列的权重(`sticky`),以确保布局的合理性和自适应性。 (2).创建按钮 创建另一个名为`button_frame`的框架,用于放置所有的按钮。使用`grid`布局管理器将`button_frame`放在主窗口的第二行第一列,并设置它同样跨越4列,占据窗口的底部一行。 定义一个包含按钮文本的列表,这个列表包含了数字、运算符等按钮文本。通过循环遍历这个列表,为每个按钮文本创建一个按钮: 首先,创建一个`lambda`函数,这个函数将当前循环到的按钮文本作为参数,传递给`self.click_event`方法。这样,当按钮被点击时,`self.click_event`方法会被调用,并执行相应的操作。 接着,创建一个`tk.Button`按钮对象,设置按钮的文本、内边距、字体等属性,以确保按钮的美观和易用性。 将前面创建的`lambda`函数与按钮对象关联起来,这样点击按钮时就会执行该函数。 使用`grid`布局管理器将按钮按行列整齐排列在`button_frame`内,确保按钮布局的合理性和美观性。同样给`button_frame`内的组件设置内外边距,并配置各行列的权重,以确保按钮布局能够自适应窗口大小的变化,保持布局的合理性和美观性。如图3.1。
图3.1 创建显示与按钮 (3)事件处理 这个方法根据用户点击按钮传入的不同key值来执行不同操作: 当key是 “=” 时,会尝试用eval函数对self.expression里存的表达式进行计算。如果计算成功,就把结果通过self.result_var设置到界面显示,并且把表达式更新为结果内容;要是计算出错,就在界面显示 “Error”,同时清空表达式。 当key是 “C”(代表清除),直接清空self.expression和self.result_var,让界面显示为空,也就是清除之前输入的内容。 当key是其他按钮(数字、运算符等)时,先判断如果当前表达式是 “0” 且点击的不是小数点,就把表达式清空,然后把点击的按钮对应的字符添加到表达式里,再通过self.result_var更新界面显示内容,如图3.2。
(4)运行截图
图3.3 计算器 2. 调查问卷 (1)导入模块与准备题库数据 首先导入tkinter库(简称为tk)用于创建图形界面,还从tkinter中导入messagebox用于弹出提示消息框。然后定义了questions列表,里面每个元组代表一道单选题,依次存放题目、正确答案、各选项内容,这就是整个测试的题库,如图3.4。
图3.4 题库 (2) 创建主窗口及相关数据结构 create_question_interface 方法:根据当前题目索引 qa_index 获取对应的问题对象 qa,然后创建标签 Label 显示问题文本,并为每个选项创建单选按钮 Radiobutton。所有这些组件都添加到根窗口中,并通过 pack() 方法进行布局管理。此外,还创建了一个 “下一题” 按钮 Button,点击后会触发 next_button 方法。 如果所有题目都已经回答完毕,则弹出一个消息框告知用户测试结束及最终得分,并关闭窗口。如图3.5,图3.6 图3.5 窗口布局
图3.6 页面布局 (3) 生成题目与选项组件创建提交按钮及关联计算得分功能 check_answer 方法:当用户选择了某个选项时,该方法会被调用以检查用户的选择是否正确。它获取用户选择的答案 user_answer 和正确答案 correct_answer,如果两者相同则增加分数 score。如图3.7。
图3.7 检查答案 (三)总结:遇到什么问题,如何解决的,结论(心得体会) 1.遇到问题 (1)界面布局错乱:手动调整窗口大小时,可能出现组件位置、大小变化不符合预期,例如按钮之间的间距不均匀、显示屏不能按规则自适应拉伸等情况,影响整体的美观度和使用体验。 (2)运算精度问题:对于一些涉及浮点数运算的复杂表达式,可能会出现精度丢失的情况,导致计算结果与预期不符,影响计算器的准确性。 (3)按钮响应不及时或卡顿:当频繁点击按钮或者进行复杂表达式输入时,界面可能出现短暂的卡顿,按钮点击后没有及时响应,影响用户的操作流畅性。 2.解决方法 (1)字体方面:可以选择更通用的字体,如系统默认字体,或者使用字体检测机制,在代码初始化时判断系统是否支持指定字体,若不支持则切换为合适的替代字体 (2)计算错误反馈:可以在捕获到eval函数抛出的异常后,对异常信息进行进一步分析,提取出更有针对性的错误提示内容展示给用户。例如,可以通过正则表达式匹配常见的语法错误模式,然后给出更易懂的提示信息, (3)按钮响应卡顿:检查代码中是否存在复杂且耗时的操作,比如在click_event方法里,如果有大量复杂的逻辑判断或者循环等,可以考虑优化算法,减少不必要的重复计算。另外,对于tkinter应用,长时间的阻塞操作可能影响界面响应,可以将一些耗时任务放到线程中执行 项目4:数据库存储
1. 创建数据库引擎建立与MySQL数据库的连接。使用 2. 定义写入数据库的函数定义一个名为 3. 读取CSV文件并写入MySQL数据库使用 4. 创建图形用户界面(GUI)使用 5. 实现查询功能在GUI中,用户可以在输入框中输入书名,然后点击提交按钮进行查询。 6. 执行SQL查询使用 7. 处理查询结果如果查询结果为空,则显示提示信息。如果查询到数据,则提取所需列,并在GUI中展示图书的详细信息。 8. 展示图书信息和图片在GUI的结果框架中,为每条查询结果创建标签以展示图书信息。同时,尝试加载与图书编码对应的图片文件,并在GUI中显示。 9. 异常处理在整个过程中,代码包含了异常处理,以确保在出现错误时能够给用户适当的反馈。 10. 运行GUI最后,如果这个脚本是作为主程序运行,将创建一个
读取文件,写入 MySQL 数据库的 bookinfo 表。如图4.1所示。
图 4.1 多文件合并
使用数据库引擎连接数据库,执行SQL查询,并将结果存储在
图 4.2数据库引擎 构建图片路径,并尝试加载图片。如果图片存在,则在GUI中显示,图片显示结果如图4.3所示
在查询和显示结果的过程中,代码包含异常处理,以确保出现错误时能给用户适当反馈
图4.4异常处理
遇到问题: 在将CSV文件数据写入MySQL数据库时,因为数据类型不匹配、字段缺失或DataFrame结构问题导致写入失败。用户在没有输入任何内容的情况下点击提交,程序会尝试执行查询,导致错误或异常。在尝试加载和显示图书封面图像时,会因为文件路径错误、文件不存在或图像文件损坏导致失败。 解决办法:
通过四个核心项目——网页信息提取和存储、数据预处理、图形用户界面(GUI)编程以及数据库存储,我在理论知识和实践技能上均取得了显著的进步。 在网页信息提取和存储项目中,我深入学习了正则表达式`lxml``BeautifulSoup` 等库的应用,掌握了多种网页内容解析的技术。这些工具和技术对于从非结构化或半结构化的HTML文档中提取有价值的信息至关重要。此外,Scrapy爬虫框架的学习为我提供了大规模数据抓取的新视角,使我能高效地从多页面网站中收集数据,并将其妥善存储至 MySQL 数据库中。这一过程不仅增强了我对数据获取的理解,还让我对数据管理和存储的重要性有了更全面的认知。 数据预处理项目是整个实训的核心部分之一,它加深了我对 `Pandas` 库的理解。通过该项目,我学会了使用 Pandas 进行 CSV 文件的读写操作,掌握了 DataFrame 的各种高级功能,如数据筛选、合并、删除及缺失值处理等。这些技能对于确保数据清洗、转换和校验的质量至关重要,直接影响数据分析结果的准确性和模型性能。例如,在处理缺失值时,我们可以选择删除含有缺失值的记录、用均值或中位数填充,甚至采用模型预测的方法来填补缺失值。此外,我还了解到了特征编码的重要性,比如独热编码(One-Hot Encoding),这对于分类数据的处理尤为关键。 GUI 编程项目的引入为我的学习增添了新的维度。借助 `Tkinter` 库,我不仅掌握了创建交互式应用程序的基本方法,还学会了如何合理布局界面元素以提升用户体验。这不仅是编程技能的提升,也是对美学和设计感知的一次洗礼。良好的 UI/UX 设计能够显著改善用户与软件之间的交互体验,这对未来成为一名全面发展的开发者来说具有不可忽视的意义。 在未来的工作和学习中,我将继续关注数据预处理领域的最新发展,积极应用所学知识解决遇到的各种挑战。同时,我也意识到持续学习的重要性,只有不断更新自己的知识体系,才能在这个快速变化的技术世界里站稳脚跟。 |
更多推荐


图1.2获取大类信息





图2.3 图书详细信息











图4.3图书查询展示
所有评论(0)