Python爬虫与MySQL应用基础案例:双色球数据爬取与存储

发布时间:2026/8/27 9:34:06
Python爬虫与MySQL应用基础案例:双色球数据爬取与存储 一.目标用Python爬取彩票网站中100条双色球历史数据中的期号、6个红球号码、1个篮球号码和奖池奖金数据并用MySQL数据库存储数据总结其中常见bug并进行修改与解析。二.本期重点与bug1.数据库创建时的优化问题。2.数据中存在逗号导致插入数据时数量不对等的问题。3.int类型数据过大超出存储上限的问题。4.再次运行会向库中重复插入数据的问题。5.SQL语句传参安全性问题。三.代码实现1.锁定数据包先打开目标网页可以发现其初始数据只有30条说明网站并不是将所有数据直接渲染完的打开F12开发者工具并清除当前抓到的所有数据包然后在网页中点击“最近100期”按钮向服务器发送请求拿到目标数据包并从中获取我们需要的信息。通过观察预览页面对比开头结尾期号可知该数据包正是目标数据包。2.数据包结构分析从返回的HTML代码中搜索目标数据发现数据是直接包含在HTML中的而数据包载荷中并不包含数据所以判定不是AJAX动态渲染应该用xpath进行数据解析。3.编码问题有时服务器返回的HTML代码中没有编码信息所以为了防止乱码我们可以使用代码response.encoding response.apparent_encoding进行自动检测编码因为requests库内部集成了专门用于编码检测的chardet库其实内部还是调用的chardet。4.代码逻辑分析从HTML源码中可以看出目标数据的层级关系所有数据都在td标签中td标签又是tbody标签的子级xpath会返回列表所以我们只需要通过父级抓到所有子级标签再遍历列表就能取出每一条数据接着再分别用xpath循环解析出各项数据并入库。因此用requests库发送请求获取响应并提取所有子级标签、连接并创建数据库这两步操作必须写在获取每条数据的循环之前。4.实操步骤分别导入本次项目所需的第三方库requests、lxml和pymysql。用requests库发送请求获取响应并提取所有子级标签并变量接收。连接并创建数据库“lottery”在连接对象中设置自动提交在该数据库中创建表“data”并指定列名和列类型。创建数据库要用try包裹防止因数据库连接失败报错导致整个系统宕机最后不管怎样都应关闭游标对象和连接对象防止内存泄露和连接占用。将所有异常捕获并给出故障提示close语句不能写在except中而要写在finally中因为如果写在except中若正常创建数据库与表则不会进行关闭操作。有了解析出的数据列表、数据库和表就可以循环取出并传递给SQL语句进行数据入库了这里选择使用百分号占位符让SQL语句能动态取值入库因为pymysql这种数据库库依赖这种占位符来做参数化查询防止SQL注入。原因f-string传参固然方便但它只会直接把参数和SQL语句做拼接不能做到SQL和参数分离让execute方法达到参数化查询的目的。原理当我们把SQL作为第一个参数传递时pymysql会先告诉MySQL服务器我要执行sql这个骨架命令当服务器发现百分号占位符时就知道这里要插入数据。然后pymysql通过专属通道把值传给服务器MySQL在执行阶段会严格遵守定义这是一个值我绝不会把它当成代码去执行数据库在“解析骨架阶段”才认命令在“绑定数据阶段”只认数据。注money数据是整型这里却用%s而不是%d占位是因为这里%s是pymysql用来做参数化查询的占位符且只认%s并不是传统的python百分号占位符替换会报语法错误四.重要bug修复与解析1.数据中存在逗号导致插入数据时数量不对等的问题试运行代码发现我们的异常捕捉捕获到了一个报错意思是你插入的数据格式与money定义的数据格式不匹配。这是因为目标数据中含有逗号分位符我们只需要用replace方法将其替换为空即可。2.int类型数据过大超出存储上限的问题运行代码再次捕捉到异常意思是第一行数据中money字段的值超出了范围。money字段是int类型此类型在MySQL中的取值范围是-2,147,483,648到2,147,483,647约正负21亿很多数据超出了这个范围这时我们就需要更改类型定义将int改为decimal该类型是MySQL中最灵活的数字类型整数、小数、超大数都能存注运行前需先删除之前报错创建的表不然类型更改不了会冲突报错补充decimal类型不加参数默认为decimal(10, 0)10代表总长0代表小数位数即可存范围在-9,999,999,999 - 9,999,999,999之间的整数且总数位数M和小数位数D需遵循图中规则非常自由。3.再次运行会向库中重复插入数据的问题如果我们再次运行代码爬虫又会重复入库100条相同数据为了避免重复我们需要给每条数据据中唯一的数据添加主键。这里的期号是唯一的相当于每条数据的id我们在定义期号的数据类型时给他添加一个主键primary key即可达到去重目的重复插入会被异常捕获有了主键也能直接通过主键索引一步定位到单条数据大幅提升查找效率